Georacer
(George Zogopoulos)
June 10, 2026, 8:48am
1
Attendees (unique) : 6
UTC0704
master ← peterbarker:pr/ahrs-send-ekf-status-report-up
opened 06:47AM - 09 Jun 26 UTC
### Summary
Have the base AP_AHRS::send_ekf_status_report assemble the packet… to be sent to the GCS rather than delegating to the AHRS backends.
### Classification & Testing (check all that apply and add your own)
- [x] Checked by a human programmer
- [ ] Non-functional change
- [ ] No-binary change
- [ ] Infrastructure change (e.g. unit tests, helper scripts)
- [x] Automated test(s) verify changes (e.g. unit test, autotest)
- [ ] Tested manually, description below (e.g. SITL)
- [ ] Tested on hardware
- [ ] Logs attached
- [ ] Logs available on request
Added an autotest for this message.
```
Board AP_Periph antennatracker blimp bootloader copter heli iofirmware plane rover sub
CubeOrange-periph-heavy * *
Durandal 0 -96 * -792 -640 32 -8 -104
Hitec-Airspeed * *
KakuteH7-bdshot 16 -88 * -24 -112 152 -8 -40
MatekF405 0 -64 * 0 24 -592 8 24
MatekH7A3 -32 16 * -200 -56 -32 -96 -88
Pixhawk1-1M-bdshot 24 48 -32 -48 -104 -152 0
SITL_x86_64_linux_gnu -5416 -1376 -5416 -5416 -1320 -5416 -1320
YJUAV_A6SE -256 -344 * -352 -312 -632 -288 -344
f103-QiotekPeriph * *
f303-MatekGPS * *
f303-Universal * *
iomcu *
mindpx-v2 48 -40 * -112 -8 192 -16 16
revo-mini 40 -80 * -32 -24 -64 -8 40
skyviper-v2450 -8
speedybeef4 96 -56 * -24 0 -200 8 56
```
### Description
The backends already mostly supplied the data required to send this report out - the data is used elsewhere in ArduPilot.
Also moves the variances and whatnot into the backends structure.
Andrew : Do all backends send variances?
Peter : DCM is the only one that doesn’t.
A : We could try to estimate the variance of DCM after the solution is calculated.
UTC0712
master ← peterbarker:pr/check-lane-switch-and-request-yaw-reset
opened 04:57AM - 09 Jun 26 UTC
### Summary
Replaces a pair of switch statements with a pair of calls on the … active backend pointer.
### Classification & Testing (check all that apply and add your own)
- [x] Checked by a human programmer
- [ ] Non-functional change
- [ ] No-binary change
- [ ] Infrastructure change (e.g. unit tests, helper scripts)
- [ ] Automated test(s) verify changes (e.g. unit test, autotest)
- [ ] Tested manually, description below (e.g. SITL)
- [ ] Tested on hardware
- [ ] Logs attached
- [ ] Logs available on request
```
Board AP_Periph antennatracker blimp bootloader copter heli iofirmware plane rover sub
CubeOrange-periph-heavy * *
Durandal -24 -16 * -8 -8 -8 -16 -16
Hitec-Airspeed * *
KakuteH7-bdshot -16 -16 * -8 -8 0 -24 -16
MatekF405 -16 -8 * -8 -8 0 -16 -16
MatekH7A3 -24 -8 * -8 -8 -8 -24 -16
Pixhawk1-1M-bdshot -24 -8 -8 -8 0 -16 -16
SITL_x86_64_linux_gnu 16 16 16 24 24 16 16
YJUAV_A6SE -16 -16 * -16 -16 -32 -16 -16
f103-QiotekPeriph * *
f303-MatekGPS * *
f303-Universal * *
iomcu *
mindpx-v2 -16 -16 * -8 -8 -8 -24 -16
revo-mini -16 -8 * -8 -8 0 -16 -16
skyviper-v2450 0
speedybeef4 -16 -8 * -8 -8 0 -16 -16
```
### Description
avoid the switch on the type, just call the method on the pointer
We had the base-class-method `AP_AHRS_Backend::check_lane_switch` already.
Merged!
UTC0715
master ← peterbarker:pr/ahrs-using-extnav-for-yaw-cleanup
opened 03:59AM - 09 Jun 26 UTC
### Summary
Groups the result of the "is the active backend using an external… yaw source" call with the other results (like... estimated yaw....)
### Classification & Testing (check all that apply and add your own)
- [x] Checked by a human programmer
- [ ] Non-functional change
- [ ] No-binary change
- [ ] Infrastructure change (e.g. unit tests, helper scripts)
- [ ] Automated test(s) verify changes (e.g. unit test, autotest)
- [ ] Tested manually, description below (e.g. SITL)
- [ ] Tested on hardware
- [ ] Logs attached
- [ ] Logs available on request
```
Board AP_Periph antennatracker blimp bootloader copter heli iofirmware plane rover sub
CubeOrange-periph-heavy * *
Durandal 56 24 * 32 128 48 24 48
Hitec-Airspeed * *
KakuteH7-bdshot 32 8 * 8 24 -16 8 -128
MatekF405 64 48 * 40 48 136 48 40
MatekH7A3 56 24 * 56 32 112 24 24
Pixhawk1-1M-bdshot 48 16 48 40 120 -64 -88
SITL_x86_64_linux_gnu 72 0 0 0 0 0 0
YJUAV_A6SE 32 16 * 24 -8 0 -8 8
f103-QiotekPeriph * *
f303-MatekGPS * *
f303-Universal * *
iomcu *
mindpx-v2 64 48 * 24 24 16 8 -144
revo-mini 80 48 * 72 72 48 64 56
skyviper-v2450 40
speedybeef4 88 48 * 48 64 216 40 64
```
(updated the usage for the extra patch)
### Description
Uses the active backend estimates for what they are good for.
With bonus hackery for DCM-bootstrapping for yaw alignment. That hackery is deliberate and has been in there since the start.
We should probably revisit why DCM is involved in these decisions. Quite possibly DCM was being used because the yaw source was un-aligned and thus yaw not available to the EKF3 and thus EKF3 not available. So this would essentially be bootstrapping the EKF from DCM's yaw. If we want a bootstrap yaw we should probably add a method to get that - which would step through each of the backends in turn and return the yaw estimate from the first good backend it finds. THis will allow e.g. CINS to be used in place of DCM for a backup estimator, for example. Once we get secondary/tertiary estimators we would probably check them for a yaw estimate before iterating the backends.
Alternatively we could expect people to bootstrap the EKF's yaw from an alternate source set (source sets postdate the T265 support, I think).
P : This is all good except we don’t handle the DCM case nicely; we switch to the EKF3 reply.
Randy : We could simply remove it.
P : Can you test it yourself?
R : I don’t have a T265 anymore, but we could do it in SITL. It’s basically a MAVLink driver.
P : Oh!
R : Let’s get rid of the old MAVLink driver, it’s less capable than the T265 and Voxl drivers. And rename the latter to be the default MAVLink.
A : There’s also a preexisting bug where even if we have an EAHRS, we always need a healthy compass to arm. Because it’s looking at AP_Compass for the health of that compass. That’s not nice.
Better rename that flag from “use compass” to “need compass to be healthy”.
But yes, let’s address this in another PR.
Approved!
UTC0739
master ← andyp1per:pr-l4-msipll-can-timing
opened 03:02PM - 04 Jun 26 UTC
### Summary
Fix DroneCAN nodes failing to come up on STM32L4 boards clocked f… rom a 32.768kHz LSE via MSI-PLL (e.g. TBS-L431, 3DR-L431).
### Classification & Testing
- [x] Checked by a human programmer
- [x] Tested on hardware
### Description
On L4 boards using `OSCILLATOR_HZ 32768` the system clock is derived from MSI locked to the LSE. Newer ChibiOS reports that MSI range at its real 3.998MHz rather than a nominal 4MHz, so SYSCLK/PCLK1 is 79,960,000 rather than 80,000,000.
`CANIface::computeTimings()` required PCLK to be an exact integer multiple of the bitrate. At 1Mbit it computed `79,960,000 / 1,000,000 = 79` (truncated, prime), found no prescaler/quanta factorisation, and returned false. `AP_Periph` ignores the init failure, so the node ran but never initialised CAN and never appeared on the bus.
The fix rounds the prescaler search to nearest and accepts the closest achievable bitrate within 1% instead of demanding an exact match. Where PCLK is an exact multiple this is a no-op, so other boards are unaffected (verified: identical register values at 80MHz). The same change is applied to the FDCAN path.
The hwdef change updates `HAL_EXPECTED_SYSCLOCK` for the LSE branch so the `system.cpp` clock static_assert matches the now-accurate 79.96MHz on these boards.
Verified on hardware: a TBS-L431-Airspeed that previously never enumerated now comes up correctly on a flight controller's CAN bus.
The bootloader carries the same timing routine (libcanard's `canardSTM32ComputeCANTimings`); that is fixed separately upstream and will follow as a submodule update once merged.
https://github.com/dronecan/libcanard/pull/92
This also fixes the current build failures on boards with this configuration
A : This change may cause very subtle side-effects which might not be easily detectable. It’s quite risky.
It’s better to change the PR so that only the L4+LSE boards get affected, which currently is only 1 or so.
UTC0754
master ← Georacer:feature/custom_plane_controller
opened 03:02PM - 29 May 26 UTC
### Summary
This PR adds support for custom Plane controllers, as `AC_CustomC… ontrol` [does for Copter](https://ardupilot.org/dev/docs/copter-adding-custom-controller.html).
### Description
A new library `AP_CustomControl` has been created, which roughly operates the same as the existing Copter counterpart.
Things that are the same:
- The overall flag is `AP_CUSTOMCONTROL_ENABLED`. The library is not part of the features list. It is meant to be explicitly, locally compiled in. SITL will compile it by default.
- Multiple custom controllers can be compiled-in and selected via `CC_TYPE`.
- An AUX switch enables or disables the controller (109).
- A basic PID example is given, which can fly a plane successfully.
Things that are different:
- The Copter custom controller is designed to return a strict control API, in the form of `Vector3f` for roll/pitch/yaw pre-mixer inputs. However this is not very useful for Plane. See below for the new API.
- Copter uses `CC_AXIS` to quickly enable/disable custom roll/pitch/yaw controllers. Since AP_CustomController now recommends unconstrained access to output functions and servos alike, The parameter has been replaced by `CC_MASK`. This is meant to be used by the developer to fence whatever function within the custom controller he pleases.
#### Recommended API
The developer has complete freedom to shape the custom controller code to his liking.
However, the following methods of `AP_CustomControl` are the recommended way to interact with the outputs:
```c++
// Write a scaled value to all channels with a function.
void set_output_scaled(SRV_Channel::Function function, float value);
// Write a pwm value to all channels with a function. Not min/max constrained. servos.cpp may overwrite it.
void set_output_pwm(SRV_Channel::Function function, uint16_t value);
// Write pwm values on a channel. Not min/max constrained. servos.cpp may overwrite it.
void set_output_pwm_chan(uint8_t chan, uint16_t value);
// Override pwm values on a channel for one loop. servos.cpp will not overwrite it.
void set_output_pwm_chan_override(uint8_t chan, uint16_t value);
```
These will reach into `SRV_Channels` and write the passed values.
This also means that **any** servo channel can be written to, even unconfigured ones. This is very useful for experimental control allocation schemes.
Typical input channels are also given quick-access and updated on every loop:
```c++
void AP_CustomControl_Backend::update_rcin_channels() {
channel_roll = &rc().get_roll_channel();
channel_pitch = &rc().get_pitch_channel();
channel_throttle = &rc().get_throttle_channel();
channel_rudder = &rc().get_yaw_channel();
channel_flap = rc().find_channel_for_option(RC_Channel::AUX_FUNC::FLAP);
channel_airbrake = rc().find_channel_for_option(RC_Channel::AUX_FUNC::AIRBRAKE);
}
```
The euler angle targets are exposed to
```c++
float get_roll_target_deg() { return _frontend.roll_target_deg; }
float get_nav_pitch_target_deg() { return _frontend.pitch_target_deg; }
float get_pitch_target_deg() { return _frontend.pitch_target_deg + _frontend.pitch_trim_deg; }
```
which are filled with
```c++
custom_control.roll_target_deg = nav_roll_cd * 0.01f;
custom_control.pitch_target_deg = nav_pitch_cd * 0.01f;
custom_control.pitch_trim_deg = g.pitch_trim;
```
#### Servo overrides
The custom controller task will run after the `stabilize` task and before the `set_servos` task.
This means that by default the safety checks mixing which happens in `servos.cpp` will still apply and may override the custom controller.
However, a method `set_output_pwm_chan_override(uint8_t chan, uint16_t value)` is given, in order to block `set_servos` from modifying this channel. This can be useful for implementing experimental/custom mixers.
#### Known drawbacks
- The parameter namespace is also `CC`. I think this might cause conflicts in the wiki?
- Due to the implementation details, output functions of GPIO (-1 enum value) cannot be addressed. Not sure how to fix that.
- AFAIK, the Plane codebase doesn't do rate controller and/or control surface bumpless transfer upon mode switches (e.g. FBWA->MANUAL). That means that there will be a step in servo output upon switching out of the custom controller and into a rate-controlling mode. The integrators are being actively reset, but this is a perfect solution. Perhaps the upcoming #32743 will fix this.
- Upon exiting the custom controller, all the main controllers are reset. Since these controllers are individually, constantly reset while the custom controller is running, there might be no reason to reset them all anew, including controllers which might not have been overriden.
#### Known unknowns
- I suspect the current RC inputs API doesn't allow accessing channels >8. I have to verify this.
- If the custom controller writes onto unused output channels, their PWM value will go from 0 whatever is requested. However, when the custom controller is suspended, the servo value will not return to 0. I do not yet know how to restore this state.
<img width="1368" height="919" alt="image" src="https://github.com/user-attachments/assets/ae199adb-25e8-4e05-9302-a11d03f59833" />
### Classification & Testing (check all that apply and add your own)
- [X] Checked by a human programmer
- [ ] Non-functional change
- [ ] No-binary change
- [ ] Infrastructure change (e.g. unit tests, helper scripts)
- [X] Automated test(s) verify changes (e.g. unit test, autotest)
- [X] Tested manually, description below (e.g. SITL)
- [ ] Tested on hardware
- [X] Logs attached
- [X] Logs available on request
Testing has been carried out in autotests as well as RealFlight.
The new autotest attempts to explore as much of the new functionality as possible. You need to read the PID example controller that is used in order to fully understand the test.
In RF, the test have been done with the FT3DXL aircraft. It is very clear when the controller banks are switched, the Custom Controller isn't tuned for this aircraft and it produces angle overshoots. Other than that, no bugs or side-effects have been observed.
Parameters and logs: [Dropbox](https://www.dropbox.com/scl/fo/i9wncuajxgpdtiocgg9p1/ACuCPd5g3Vrdy4cHC1xioi4?rlkey=ay0d4q8ha7o4haa9r8xxsjclt&st=5onxxaek&dl=0)
A : Let’s make sure that the custom controller won’t run at all nor touch the main controller integrators if it’s turned off.
A : The parameter documentation is failing CI.
UTC0830
opened 07:43AM - 05 Jun 26 UTC
## Bug Report
Posting this for recordskeeping.
The SRTM3 continent files seem … to fail our prearm check for the tile version.
### Issue details
Run a simulation with
```bash
sim_vehicle.py -v ArduPlane -f quadplane --console --map --custom-location=47.38719,18.9577,99,0
```
Set `TERRAIN_OPTIONS=1`, `TERRAIN_FOLLOW=1536`.
Delete any [downloaded terrain files](https://terrain.ardupilot.org/continentsdat3/) in the `terrain` directory.
Paste from the Eurasia dataset the following:
```
├── N46E047.DAT
├── N46E048.DAT
├── N46E049.DAT
├── N47E017.DAT
├── N47E018.DAT
├── N47E019.DAT
├── N48E047.DAT
├── N48E048.DAT
└── N48E049.DAT
```
Then reboot.
This yields a preflight failure:
<img width="447" height="594" alt="Image" src="https://github.com/user-attachments/assets/5db48498-24e7-464f-906e-a6a1ef5565fb" />
**Version**
4.7.0-beta3 and -beta5
**Platform**
[ ] All
[ ] AntennaTracker
[ ] Copter
[X] Plane
[ ] Rover
[ ] Submarine
**Airframe type**
N/A
**Hardware type**
SITL
**Logs**
Reproducible in SITL, but available upon request.
The bug has been reproduced by Peter.