Attendees (unique) : 8
UTC0804
master ← jfbblue0922:pr-apply_JRE_serial_v2_of_JRE_rangefinder
opened 06:33AM - 18 Jun 26 UTC
### Summary
Applied JRE serial Protocol Ver.2 of Range Finder by JAE.
### … 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)
- [X] Tested on hardware
- [ ] Logs attached
- [X] Logs available on request
### Description
This PR adds supported for JRE Serial Ver.2, the serial protocol used by JAE's Range Finder : JRE-10VA.
The JRE-10VA will be released in the future.
Still pending change requests.
UTC0805
master ← peterbarker:pr-claude/viewpro-angle-rad-deg-thing
opened 08:08AM - 20 Jun 26 UTC
### Summary
Tidies up ViewPro sending my eliminating degrees intermediates.
…
### 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
Tortured a bit locally by making sure we run through these checks, breaking the calculation and fixing it again.
```
Board,copter
CubeOrangePlus,-48
```
These paths are well cross by the autotest suite.
### Description
Add AP_MOUNT_VIEWPRO_RAD_TO_OUTPUT and use it for the target pitch/yaw angles and for the vehicle attitude sent in the M_AHRS packet, taking the values from the AHRS in radians rather than degrees. This removes the intermediate radians-to-degrees conversions and the now-unused AP_MOUNT_VIEWPRO_DEG_TO_OUTPUT scalar.
Fixes a very small issue where we would truncate the vehicle yaw to integer degrees before multiplying it again to scale it to put in the packet.
Peter : The Viewpro driver wants its own units. So there’s no reason to convert to degrees first.
Also fixed an unnecessary cast to integer, which truncated the decimals.
Merged!
UTC0811
master ← peterbarker:pr-claude/msp-send-fix
opened 04:58AM - 05 Aug 26 UTC
### Summary
Fix inverted check when sending MSP traffic
### 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
### Description
Original betaflight line: https://github.com/betaflight/betaflight/blob/master/src/main/msp/msp_serial.c#L311 - you can see we inverted the pending check when porting ("empty" vs "pending" and both lines have a `!`)
tx_pending doesn't make a huge amount of sense when our writes are non-blocking anyway. So just make sure the thing fits.
Merged!
UTC0811
master ← andyp1per:pr-ins-icm56686
opened 10:51AM - 08 Aug 26 UTC
### Summary
Adds ICM-56686 support to the Invensensev3 driver. It shares the IC… M-456xy programming model, so this is a variant of that path rather than a new driver.
### Classification & Testing (check all that apply and add your own)
- [x] Checked by a human programmer
- [x] Tested on hardware
Running on a board with an ICM-56686 as the only IMU: probes, calibrates and produces sane gyro and accel data in high resolution mode. The board is not in tree, so no in-tree hwdef selects the part yet.
### Description
The FIFO header bits and the 20 byte high resolution packet are identical to the ICM-45686, so the parser and accumulator are untouched. Two things differ, both from DS-000563 rev 1.0.
The register block from `PWR_MGMT0` upwards sits 4 higher - `PWR_MGMT0` at 0x14, `FIFO_DATA` at 0x18 - while `WHO_AM_I` at 0x72 and the IREG window at 0x7C are common to both parts. `reg456()` applies the offset at runtime and passes anything at or above `WHO_AM_I` through unchanged, which keeps the existing 456xy call sites rather than duplicating them for one constant.
`SREG_CTRL` resets to 0x0A here, selecting 20 bit sensor registers and big endian data, and the endianness applies to the FIFO as well. It has to be cleared before any sample is read or every value comes back byte swapped. The ICM-45686 needs no equivalent write, which is why the 456xy path did not already have one.
`FS_SEL` 0 selects 4000dps and 32g on both parts, so the scaling is shared. `WHO_AM_I` reads 0x08 against 0xE9 at the same address, so probing needs no heuristics.
One address is inferred rather than confirmed: `IOC_PAD_SCENARIO_AUX_OVRD` is not listed in DS-000563, and is only reached under `ICM45686_CLKIN`, which no board currently defines. It is noted as such in the code.
Andy : This flies very well, I tested in ACRO.
Merged!
UTC0825
master ← Georacer:pr/last_letter_ci
opened 12:31PM - 11 Aug 26 UTC
### Summary
Adds a CI test for the last_letter simulation backend.
### Cla… ssification & Testing (check all that apply and add your own)
- [x] Checked by a human programmer
- [ ] Non-functional change
- [ ] No-binary change
- [x] 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
- [x] Logs attached
- [ ] Logs available on request
SITL log: https://www.dropbox.com/scl/fi/77cdmqabx0lq48s4qostf/00000003.BIN?rlkey=bos9sbvkrglk9q9n20s2upxda&st=6fkdta46&dl=0
### Description
Adds a new github workflow which:
- Builds plane SITL.
- Pulls a pinned version of the last_letter_ardupilot binary, its dynamic library and the models folder.
- Runs a duplicate of the `LOITER` test.
P : Copy from AutoTestCAN, do it like that.
Try to go through build_ci.py
The plane build in the .yml is likely redundant.
UTC0830
master ← rishabsingh3003:master-replay-snapshot
opened 12:12PM - 11 Aug 26 UTC
### Summary
LOG_REPLAY=1 needs LOG_DISARMED, so replay logs grow from boot … and are
impractical to leave enabled in normal operation. LOG_REPLAY=2 writes an
EKF3 state snapshot to the log at arming and runs the replay stream only
while armed
### 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)
- [x] Tested on hardware
- [ ] Logs attached
- [x] Logs available on request
P : I’m not a fan of the approach. If you need the replay logs, you need the full thing.
Rishabh : Yes, it’s not as good, but it’s pretty close.
It’s useful to have this available and on all the time in production, after you introduce a new feature.
G : I know of use-cases where the response time needs to be counted in minutes. Rebooting eats into your margin.
P : I don’t think replay is something you should deploy in production. It eats into your resources and clogs your logging. I don’t like the extra complexity.
Barometric altitude drift, uBlox reported precision and other problems are also related to long waiting times.
R : It’s okay. I’ll try to get tridge’s opinion too.
UTC0838
master ← andyp1per:pr-bdshot-gcr-validation
opened 10:47AM - 08 Aug 26 UTC
### Summary
The GCR decode table mapped the sixteen quintets the encoding never… emits to nibble 0, which is indistinguishable from the legitimate 0 at index 25. A corrupt quintet therefore decoded silently, leaving the four bit checksum as the only guard against a bad eRPM reaching the harmonic notch.
### Classification & Testing (check all that apply and add your own)
- [x] Checked by a human programmer
Table verified exhaustively against the old one: the sixteen entries now marked `0xff` are exactly the codes the encoder cannot produce, the sixteen valid entries are unchanged and cover all sixteen nibbles, and all 65536 words built only from valid quintets decode to the same value as before. Every word containing an impossible quintet is rejected. Builds for a bdshot target.
### Description
Betaflight measures 5-8% of bidirectional DShot frames failing to decode with motors running, so this path takes corrupt input constantly and by design - it is not an error case. What it did with that input was to map any impossible quintet onto nibble 0 rather than rejecting it, because 0 was also the table's "no such code" filler. The checksum was then the only thing standing between a corrupted frame and an accepted eRPM, and four bits lets roughly one in sixteen through.
The value matters beyond a telemetry display: it drives RPM-referenced harmonic notch tracking, so a wrong eRPM moves the notch off the real motor frequency.
Impossible quintets are now marked `0xff` and the word is rejected if any of its four nibbles came from one. The test is a single OR and compare, on a path that already computes a checksum.
The four lookups had to be pulled out into named values rather than left as the running `|=` accumulation: a valid result uses all sixteen bits, so there is no spare bit for a sentinel to survive the shifts - only the top quintet's would land clear of the result.
Andy : This change improves error detection on noisy ESCs.
It still needs flight testing.
It might help with RPM spikes during spinup.
UTC0844
master ← andyp1per:pr-ins-sensor-health-race
opened 10:47AM - 08 Aug 26 UTC
### Summary
`update()` cleared the IMU health flags every main loop and relied … on the backends to set them true again a few microseconds later. Those flags are read from other threads, so the window is observable, and at ELRS telemetry rates it produces a continuous "Bad Gyro Health" on a vehicle whose gyro never missed a sample.
### Classification & Testing (check all that apply and add your own)
- [x] Checked by a human programmer
- [x] Tested on hardware
Reproduced with CRSF telemetry at 199Hz: constant "Bad Gyro Health" on the transmitter with no corresponding fault anywhere. Gone after the change. Builds and runs in SITL.
### Description
`AP_InertialSensor::update()` set `_gyro_healthy`/`_accel_healthy` false for every instance at the top of the loop, on the assumption that the backends would republish immediately afterwards. That assumption holds for readers on the main loop, but `AP_RCTelemetry::check_sensor_status_flags()` runs from the CRSF frame handler on the RC input thread and samples the flags asynchronously. The higher the telemetry rate, the more often it lands inside the window.
It cannot be seen in a log. `IMU.GH` is written from the main loop, which by construction is not inside `update()` at the same time, so it reads 1 even when logged at loop rate - the flag is only ever false while nothing that logs it can look.
Rather than lock a flag that has no reason to change, the central clear is dropped and `update_gyro()`/`update_accel()` assign it exactly once per cycle: true when a fresh sample was published, false when there was none or the instance has been killed. The value then only changes when the health actually changes.
Andy : The sensor health gets written multiple times, so in dual core systems the reads might be on invalid data.
P : Why doesn’t this affect us in Linux boards which also spin multiple threads?
UTC0849
opened 02:45AM - 03 Aug 26 UTC
DevCallEU
AndyP and I have had discussions about the power up state of VTX power when cont… rolled by a GPIO.
Andy believes it should default to powered after boot to avoid users thinking something is wrong with the board (having not read the documentation on VTX power control)
My position is that its a safety issue (shoot down someone flying already on your channel...since you cant power the VTX off until boot completes and the user takes an action to power off) and a power issue (many VTX will overheat in the pits if on...user should power it on just before takeoff)
To avoid review conflicts, I have modified my review tools to adhere to Andy's position, but I think it worth discussing....I know my flying buddies in MultiGP racing agree with my view.
A : Lots of vehicles don’t have a VTX power switch. It’s always on. And at the end of the day we can leave it to the board vendor to decide their default.
Michelle : I think we’ll get a lot of support issues if we start with VTX off by default. I think Betaflight has this on by default.
Besides I bet a lot of people power the VTX directly from the battery.
A : We can’t fix this problem. We can change it for some boards, but it will bring on support tickets.
Randy : Doing something worse because it reduces support doesn’t sound like a good strategy. Nor contributing to an existing problem.
M : Besides, people set up their quads at home, not at the field.
P : We could default to what Betaflight does, but have the Methodic Configurator and the wiki guide the users to change from the default.
Amilcar : Yes, that’s doable.
UTC0859
master ← andyp1per:pr-ins-gyro-cal-rotation
opened 10:44AM - 08 Aug 26 UTC
### Summary
Gyro calibration zeroed `_board_orientation` so its own samples cam… e out in board frame, but that field is global, so the accel lost its rotation too. DCM's startup alignment reads the last accel published in that window, so on a board whose orientation flips Z it aligns 180 degrees out and takes minutes of drift correction to walk back, failing the attitude pre-arm throughout.
### Classification & Testing (check all that apply and add your own)
- [x] Checked by a human programmer
- [x] Tested on hardware
Found on a board with an `AHRS_ORIENTATION` that flips Z, where the DCM attitude pre-arm failed for minutes after every boot. With the change it passes immediately. Builds and runs in SITL.
### Description
`_init_gyro()` saved `_board_orientation`, set it to `ROTATION_NONE` for the duration of the calibration and restored it afterwards. The intent was to keep the calibration samples in board frame, but `_board_orientation` is also applied by `_rotate_and_correct_accel()`, so every accel published during the calibration is unrotated as well.
That matters because the value outlives the calibration. `_accel[0]` holds the last one, and `AP_AHRS_DCM::reset()` reads it a few lines later in `init_ardupilot()` to set the initial attitude, gating only on the vector magnitude - a board-frame 9.81 passes. On an upright board the two frames agree and nothing shows, which is why it has gone unnoticed; it needs an orientation that flips Z to be visible at all.
The gyro backend already skips the offset subtraction while `_calibrating_gyro` is set, so the rotation is now skipped in the same place and `_board_orientation` is left alone. The accel is then never published in board frame, and DCM aligns level whether the value it reads is fresh or stale.
Teaching DCM to reject a stale accel instead would leave the board-frame value visible to everything else that reads the accel during calibration, so it treats the symptom rather than the cause.
Andy : My board is placed upside-down and getting DCM errors.
This one fixes the issue.
Randy : I suspect EKF and DCM don’t agree on startup when the board is upside-down.
P : Strange that I’ve never had problems.
Randy : But you are running Plane, not Copter.
UTC0903
master ← andyp1per:pr-static-notch-bug
opened 10:18AM - 29 Jul 26 UTC
### Summary
`INS_HNTC2_MODE` and `INS_HNTC2_HMNCS` are applied as *defaults* in… side the pre-4.2 fixed-notch conversion, gated on the notch being disabled. Defaults are not stored, so the gate closes the moment `INS_HNTC2_ENABLE` is saved and both parameters revert to their table defaults on the next boot. Two consequences: a vehicle upgrading from 4.1 gets its converted fixed notch turned into a throttle-tracking notch on all harmonics one reboot later, and anyone setting HNTC2 up as a static notch sees MODE go 0 -> 1 across a reboot and has to set it explicitly to make it stick.
Save the values instead, and only when an old fixed notch was actually converted.
### Classification & Testing (check all that apply and add your own)
- [x] Checked by a human programmer
- [x] Tested manually, description below (e.g. SITL)
SITL A/B against a synthesised pre-4.2 eeprom holding the old fixed notch (`INS_NOTCH_ENABLE=1 ATT=30 FREQ=95 BW=25`):
| | boot that converts | next reboot |
|---|---|---|
| before | MODE 0, HMNCS 1 | **MODE 1, HMNCS 3** |
| after | MODE 0, HMNCS 1 | MODE 0, HMNCS 1 |
Separately, on a wiped eeprom: enabling `INS_HNTC2_ENABLE` and rebooting used to move `INS_HNTC2_MODE` from 0 to 1 and `INS_HNTC2_HMNCS` from 1 to 3. Both are now stable across reboots.
### Description
The intent of the two `set_default_by_name()` calls was to make a notch converted from the old fixed `INS_NOTCH_` come up as a static notch on the first harmonic. That intent is correct, but expressing it as a default makes the effective default depend on the runtime value of another parameter, and it is never persisted, so it evaporates as soon as the conversion saves `INS_HNTC2_ENABLE`.
This deliberately does not make `INS_HNTC2_MODE` default to 0 in general. That would match what a GCS shows while the notch is off, and it would let a `defaults.parm` configure a static HNTC2 with `ENABLE` alone, but it would also silently switch every vehicle currently flying HNTC2 with an unsaved MODE from throttle tracking to static. The documented default has always been 1, since the parameter tables are what `param_parse` reads, so this makes behaviour match the documentation rather than changing anyone's filter configuration in the field.
Andy : There’s a bug where if you configure two static notches, on reboot one will get converted to a throttle notch.
This is due to parameter conversion code.
M : Why not remove the conversion code, 4.2 is too old.
Randy : Yes, let’s remove it.
P : We should have a process for removing old conversion code and updating old parameters.
UTC0809
master ← amilcarlucas:generate_pdef_xml
opened 04:37PM - 21 Oct 25 UTC
Amilcar : It puts documentation on the release directory. You get documentation for every release, with a label and a git hash. Next to the firmware folders.
Randy : Our versioned parameters stopped uploading at Index of /Parameters/versioned/Copter after 4.6.0.
Amilcar : I was creating those directories manually. But we should really be automating it.
P : We still need to find a way for the wiki to read them.
Amiclar : I would also like to put it in the .apj, so that the GCS can pull it upon connection.
P : It won’t fit on an .apj, but we can definitely put the parameter URL in the .apj metadata.
Amilcar : Zipped parameters are about 120kB. The parameters FTP is a lot bigger.
Randy : Let’s be careful with what we add in the firmwares directory, as Peter says, because there are a lot of automated consumers (GCSs etc) of the firmware directory.
Amilcar : We could also extend the embedded information to the set of supported MAVLink messages and the .bin log field documentation.
P : The robot has some recommendations too.
UTC0935
master ← amilcarlucas:decode_ids_lib
opened 07:20PM - 29 Jul 26 UTC
### Summary
Refactor the decode_devid script to be callable by other python s… cripts
Also fix the lining issues and provide tests and examples
### Classification & Testing (check all that apply and add your own)
- [x] Checked by a human programmer
- [x] Non-functional change
- [x] No-binary change
- [x] Infrastructure change (e.g. unit tests, helper scripts)
- [ ] Automated test(s) verify changes (e.g. unit test, autotest)
- [x] Tested manually, description below (e.g. SITL)
- [ ] Tested on hardware
- [x] Logs attached
- [ ] Logs available on request
### Description
Here is the output of the `python .\example_usage_decode_devid.py`
```
======================================================================
EXAMPLE 1: Decoding a specific device ID
======================================================================
Input device ID (hex): 0x00051001
Input device ID (dec): 331777
Decoded components:
Bus type: I2C (1)
Bus: 0
Address: 0x10 (16)
Device type: 0x05 (5)
Device name: DEVTYPE_BMM150
Is DRONECAN: False
Formatted output:
bus_type:I2C(1) bus:0 address:16(0x10) devtype:5(0x5) DEVTYPE_BMM150
======================================================================
EXAMPLE 2: Processing multiple device IDs
======================================================================
IMU device with I2C bus
Device ID: 0x00031801
Result: bus_type:I2C(1) bus:0 address:24(0x18) devtype:3(0x3) UNKNOWN
Compass with SPI bus
Device ID: 0x0006b001
Result: bus_type:I2C(1) bus:0 address:176(0xb0) devtype:6(0x6) DEVTYPE_LSM9DS1
Barometer with I2C bus
Device ID: 0x00000c02
Result: bus_type:SPI(2) bus:0 address:12(0xc) devtype:0(0x0) UNKNOWN
======================================================================
EXAMPLE 3: Browsing available sensor types
======================================================================
Available Compass Types:
0x01: DEVTYPE_HMC5883_OLD
0x02: DEVTYPE_LSM303D
0x04: DEVTYPE_AK8963
0x05: DEVTYPE_BMM150
0x06: DEVTYPE_LSM9DS1
... and 19 more
Available IMU Types: 35 types
Available Barometer Types: 24 types
Available Airspeed Types: 11 types
======================================================================
EXAMPLE 4: Using with string input (hex or decimal)
======================================================================
Parsing from hex string '0x00031801': 202753
Parsing from decimal string '3227137': 3227137
Are they equal? False
```
Here is the output of the `python .\test_decode_devid.py` test:
```
================================================================================
Testing individual library functions
================================================================================
Testing parse_device_id():
parse_device_id('0x00051001') = 331777
parse_device_id('331777') = 331777
parse_device_id('0x0006b001') = 438273
Testing decode_device_id():
Input: 0x00051001
Bus type: I2C (1)
Bus: 0
Address: 0x10
Device type: 5
Is DRONECAN: False
Testing get_device_type_name():
Compass 0x05: DEVTYPE_BMM150
IMU 0x09: DEVTYPE_BMI160
Testing format_device_info():
bus_type:I2C(1) bus:0 address:16(0x10) devtype:5(0x5) DEVTYPE_BMM150
================================================================================
Testing decode_devid.py vs decode_devid_lib.py
================================================================================
✓ Compass - I2C bus, BMM150
Device ID: 0x00051001, Flag: -C
✓ Compass - I2C bus, HMC5883
Device ID: 0x00071E05, Flag: -C
✓ Compass - I2C bus, AK8963
Device ID: 0x0001E004, Flag: -C
✓ IMU - I2C bus, ACC_MPU6000
Device ID: 0x00091301, Flag: -I
✓ IMU - SPI bus, BMI160
Device ID: 0x00000902, Flag: -I
✓ Barometer - SPI bus, BMP280
Device ID: 0x00000302, Flag: -B
✓ Barometer - SPI bus, MS5611
Device ID: 0x00040B02, Flag: -B
✓ Airspeed - SPI bus, MS4525
Device ID: 0x00000102, Flag: -A
✓ Airspeed - SPI bus, MS5525
Device ID: 0x00020302, Flag: -A
✓ DRONECAN compass
Device ID: 0x00010083, Flag: -C
✓ DRONECAN IMU
Device ID: 0x00010183, Flag: -I
✓ Minimal device ID
Device ID: 0x00000001, Flag: -C
✓ Maximum device ID
Device ID: 0xFFFFFFFF, Flag: -I
================================================================================
Test Results: 13 passed, 0 failed
================================================================================
✓ All tests passed! Both scripts produce identical output.
```
I did break the _lib script on purpose and the test code found the issues.
Should it be merged like this or should I just change the original script?
P : Some more comments from the robot.