Skip to content

Use clamp-then-shrink for trust-box construction at variable bounds#570

Open
rjoomen wants to merge 1 commit into
tesseract-robotics:masterfrom
rjoomen:fix/trust-box-clamp-then-shrink
Open

Use clamp-then-shrink for trust-box construction at variable bounds#570
rjoomen wants to merge 1 commit into
tesseract-robotics:masterfrom
rjoomen:fix/trust-box-clamp-then-shrink

Conversation

@rjoomen

@rjoomen rjoomen commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

This is a follow-up to #472, which fixed the trust box extending past variable bounds by sliding the full-width box inside [lb, ub] (the "slide always" policy). That fix kept the box well-formed, but preserving the full 2·box_size width let the QP step exceed box_size on the interior-facing side whenever a bound was active — breaking the trust-region invariant ‖p‖∞ ≤ box_size that the SQP merit-improve machinery relies on, even for iterates strictly inside their bounds (within a trust-radius of a bound).

This PR replaces the slide-always policy with clamp-then-shrink: clamp the iterate into [lb, ub], then strict-shrink the box against the bounds.

$$x_i^{\text{eff}} = \mathrm{clamp}(x_i, l_i, u_i), \qquad \text{box}_i = [\max(x_i^{\text{eff}} - \Delta_i, l_i),\ \min(x_i^{\text{eff}} + \Delta_i, u_i)]$$

It keeps the bug-fix property from #472 (box stays well-formed at and beyond bounds) while restoring the trust-region invariant for in-bounds iterates.

Behavior

  • In-bounds iterates: the clamp is a no-op and ‖p‖∞ ≤ box_size is restored — the contract the merit-improve ratio ρ depends on.
  • Near a bound: the box width shrinks monotonically from 2Δ (centered) to Δ (at the bound), instead of keeping the full 2Δ width (as under Fix bounds problem #472's slide-always policy) and allowing an in-bounds step that exceeds the trust radius Δ on the interior-facing side.
  • Iterate drifted outside [lb, ub] (failed step, bad warm-start, failed-solve recovery): the box still stays well-formed (non-empty, non-inverted), so the QP solver does not error out.

Scope

Applied consistently to both QP-problem variants (IfoptQPProblem, TrajOptQPProblem) and the trajopt_sco optimizer.

Testing

New unit test trust_box_floor_unit covers the in-bounds invariant, the near-bound ramp, the at-bound floor, and the outside-bounds well-formedness across all three code paths.

@rjoomen
rjoomen force-pushed the fix/trust-box-clamp-then-shrink branch from 713c74b to 424b37b Compare July 23, 2026 13:05
Near a variable bound the trust box was built by sliding the full-width
box inside [lb, ub] (the "slide always" policy). That kept the 2*box_size
width but let the QP step exceed box_size on the interior-facing side
whenever a bound was active, breaking the trust-region invariant
||p||_inf <= box_size that the SQP merit-improve machinery relies on --
even for iterates strictly inside their bounds.

Switch to clamp-then-shrink: clamp the iterate into [lb, ub], then
strict-shrink the box against the bounds. For in-bounds iterates this
restores ||p||_inf <= box_size; when the iterate has drifted outside its
bounds (failed step, bad warm-start) the box still stays well-formed
(non-empty, non-inverted), so the QP solver does not error out. Applied
to both QP problem variants (IfoptQPProblem, TrajOptQPProblem) and the
trajopt_sco optimizer. Verified by trust_box_floor_unit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rjoomen
rjoomen force-pushed the fix/trust-box-clamp-then-shrink branch from 424b37b to 4f2d9ac Compare July 23, 2026 13:08
@rjoomen
rjoomen requested a review from Levi-Armstrong July 23, 2026 13:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant