Aircraft: Align 900 traditional helicopter, CubeOrangePlus, ArduHeli, single-GPS DroneCAN setup, no external gyro (H_TAIL_TYPE=0, servo tail).
Background
We wanted to add a LightWare GRF500 rangefinder to this heli for altitude sensing. GRF250/GRF500 support requires ArduCopter 4.7+ (RNGFND_TYPE=45, added in 4.7), so we upgraded the flight controller from our previous 4.6.3 to 4.7.1 specifically to support the new sensor.
What we did, in order
- Installed the GRF500 on a serial port (
SERIAL4,RNGFND1_TYPE=45), upgraded firmware 4.6.3 → 4.7.1. - Initially got “Bad LiDAR Health.” Root cause was our own misconfiguration —
RNGFND1_MAXwas left at 100 instead of 500 for the GRF500. Fixed. - Separately noticed the GRF500 isn’t mounted centrally on the airframe, and
RNGFND1_POS_X/Y/Zare still at 0/0/0 (uncorrected lever-arm offset) — flagged as a possible contributor to noisy surface-tracking, not yet resolved. - Flew several 4.7.1 flights. Loiter felt noticeably less settled than before. One flight showed the position controller’s altitude target swinging ~5m during Loiter, driving large collective excursions — traced to
SURFTRAK_MODE=1actively terrain-following once the new rangefinder was present, which wasn’t physically possible pre-upgrade. - Attempted an Auto mission (10 waypoints) on 4.7.1 — aborted back to Stabilize after ~9 seconds, before reaching the first waypoint. Aircraft felt unstable during the attempt.
- By this point the GRF500 had gone silent entirely (no rangefinder data at all in the log) — so the later instability isn’t a rangefinder/surface-tracking artifact.
- Rolled back to 4.6.3 (reflashed via Mission Planner
CubeOrangePlus-helibuild, reloaded our pre-upgrade parameter file). - Re-flew the same 10-waypoint mission on 4.6.3 — completed cleanly, all waypoints reached in sequence.
Log analysis (Claude-assisted — flagging this so you can weight it accordingly)
We used Claude to do a first pass through the dataflash logs comparing the last 4.7.1 flight against the first clean 4.6.3 flight after rollback, trying to isolate what actually changed. Being upfront: this was AI-assisted analysis of our own logs, not a from-source investigation — we’re posting because we couldn’t get further ourselves and don’t want to over-claim a root cause we haven’t actually confirmed.
What we found:
- Loiter position-hold, filtered to hands-off segments on both versions, came out statistically similar (mean/std position error within noise of each other). We can’t confirm a general Loiter-controller regression from this.
- The Auto mission comparison is the strongest signal. Same mission file, identical waypoints, identical
WP_ACC/WP_SPD/WP_JERK/WP_RADIUS_Mparams on both flights (confirmed the SI-unit param migration carried the tuned values over correctly). Despite the 4.7.1 attempt having a shorter first leg (~14m vs ~27m on 4.6.3), it commanded a larger pitch/roll lean and its actual velocity overshot its own commanded velocity by >2× (actual ~2.4 m/s vs commanded ~1.2 m/s, exceeding the configured 2 m/sWP_SPDcap). The 4.6.3 flight tracked its own commanded velocity much more proportionately over a longer leg. - We went looking for a specific cause in the S-curve/WPNav code and found two candidate issues from this exact release window: #31584 (“Ch6 tuning of WP Speed overshoots during the beginning of the first leg”) and #32724 (“SCurve calculation formula” sign error, fixed by #32730). We pulled the actual
SCurve.cppsource at bothCopter-4.6.3andCopter-4.7.1tags to check — the #32724 fix genuinely is present in 4.7.1 and absent in 4.6.3, which is the opposite direction needed to explain what we saw, and the term in question depends on initial velocity, which was ~0 in both our flights anyway. So we’re ruling that specific bug out rather than force-fitting it. - We didn’t manage to find the actual root cause. That’s why we’re posting rather than filing a definitive bug report.
What we’re hoping for
- Does this match a known TradHeli-specific WPNav/PosControl behavior change between 4.6 and 4.7?
- Anything else in the logs worth checking that we haven’t thought of (EKF source weighting, heli-specific attitude/PosControl interaction, something in
ATC_ACCEL_*→ATC_RAT_*_PDMX/SMAXrenaming)? - Happy to provide anything else needed to reproduce.
Log files available
From this repo, under logs/ALIGN/1/:
| Flight | Firmware | Relevance |
|---|---|---|
2026-09-10 14-47-18/2026-09-10 14-47-18.bin (+ .param) |
4.7.1 | The aborted Auto mission — main evidence, entered Auto at ~160s, aborted ~169s |
2026-09-10 15-21-50/2026-09-10 15-21-50.bin (+ .param) |
4.6.3 | The equivalent successful Auto mission, same mission file, entered Auto ~335s, completed all 10 WPs by ~469s |
2026-09-10 13-19-10/2026-09-10 13-19-10.bin |
4.7.1 | Shows the SURFTRAK-driven altitude/collective chasing while the rangefinder was still reporting (separate observation, probably not related to the Auto-mode finding) |
|---|---|---|
Align/params.param |
4.6.3 | Our pre-upgrade baseline parameter file, for reference |