Loiter/Auto instability after 4.6.3 → 4.7.1 upgrade

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

  1. Installed the GRF500 on a serial port (SERIAL4, RNGFND1_TYPE=45), upgraded firmware 4.6.3 → 4.7.1.
  2. Initially got “Bad LiDAR Health.” Root cause was our own misconfiguration — RNGFND1_MAX was left at 100 instead of 500 for the GRF500. Fixed.
  3. Separately noticed the GRF500 isn’t mounted centrally on the airframe, and RNGFND1_POS_X/Y/Z are still at 0/0/0 (uncorrected lever-arm offset) — flagged as a possible contributor to noisy surface-tracking, not yet resolved.
  4. 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=1 actively terrain-following once the new rangefinder was present, which wasn’t physically possible pre-upgrade.
  5. 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.
  6. 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.
  7. Rolled back to 4.6.3 (reflashed via Mission Planner CubeOrangePlus-heli build, reloaded our pre-upgrade parameter file).
  8. 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_M params 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/s WP_SPD cap). 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.cpp source at both Copter-4.6.3 and Copter-4.7.1 tags 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/SMAX renaming)?
  • 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

Based on what I know about 4.7, I suspect that it is due to changes in the attitude controller command model. If you have your ATC_INPUT_TC set to 0.2 or greater then that is now more like a time constant of 0.5. So I would suggest cutting the parameter by 50% and see if that helps the loiter and auto modes behave better

Ok. Well I looked at your log. I can see that you have done no tuning; well maybe very little to the yaw axis. So my first suggesting would be to tune the attitude controller. My comment above about the ATC_INPUT_TC doesn’t apply to you as you didn’t actually change it.

Please take the time to tune the attitude controller using the tradheli tuning wiki. Then try again and see if it behaves better