Skip to content

Tune collocated integral-error saturation to tendon scale - #135

Open
mstoelzle wants to merge 2 commits into
mainfrom
codex/tune-collocated-integral-saturation
Open

Tune collocated integral-error saturation to tendon scale#135
mstoelzle wants to merge 2 commits into
mainfrom
codex/tune-collocated-integral-saturation

Conversation

@mstoelzle

@mstoelzle mstoelzle commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • replace the collocated optimizer's fixed gamma=10 with a physically interpretable default tendon-error scale of e_sat = 10 mm, i.e. gamma = 100 1/m
  • expose the scale as --integral-error-saturation-scale (meters) and reject non-finite or non-positive values
  • reject non-finite gamma values universally in PIDControl before positivity/SPD validation
  • document the trajectory-based derivation and prominently mark the committed Section V.d data and plots as stale

How we arrived here

PR #133 corrected the built-in saturation from the former tanh(gamma * e) expression to the unit-preserving

sat(e) = tanh(gamma * e) / gamma,
gamma = 1 / e_sat.

The collocated control-gain optimizer integrates only tendon-length errors, so every controlled coordinate has units of meters and a scalar gamma has units 1/m. The optimizer had retained gamma=10, which now means e_sat=100 mm: the full segment length and far outside the observed error regime. It retained 99.3% of the largest initial error, making saturation effectively inactive.

I transformed every saved configuration in the six committed initial and optimized collocated trajectories into tendon coordinates and compared them with the tendon-length setpoints:

Quantity Tendon 1 Tendon 2 Tendon 3
undeformed length -100.00 mm -100.00 mm -100.00 mm
setpoint -85.49 mm -96.41 mm -100.05 mm
initial error 14.51 mm 3.59 mm -0.05 mm

Apart from the exceptional 14.51 mm reference step, all observed initial/transient absolute errors across the saved trajectories remain below 3.85 mm.

A 10 mm saturation scale is therefore a deliberate boundary between the large reference step and the ordinary closed-loop error regime:

  • at 14.51 mm, sat(e)=8.96 mm, reducing integral accumulation by 38.25%
  • at 3.85 mm, 95.35% of the error is retained
  • at 1 mm, 99.67% is retained

This limits windup during the large step without materially reshaping the ordinary transient and regulation errors.

Result status and regeneration order

Important

All currently committed Section V.d MAT files and derived plots must now be considered stale. The collocated results were generated with the former non-unit-preserving saturation and the former gamma setting. This PR intentionally does not replace any result artifacts.

The complete Section V.d results should be regenerated only after:

  1. this PR has been merged; and
  2. the other control-gain-optimization defects in Select best optimization batches independently in collocated and synergistic plots #128 and Fix gain-optimization history pairing and reject non-finite candidates #129 have been fixed.

A one-iteration temporary smoke run completed the simulation/save path, but it reproduced the non-finite optimized gains tracked in #129. Its setpoint rollout also warned that it had not reached steady state. Those outputs were written only under /tmp and are not included here.

Validation

  • ruff check and ruff format --check on the collocated optimizer
  • python -m py_compile on the collocated optimizer
  • pytest -q tests/control/test_pid_control.py: 41 passed
  • numerical saturation check at 14.51 mm, 3.85 mm, and 1 mm
  • one-iteration collocated end-to-end smoke run to temporary output, confirming the new code path and reproducing the separate Fix gain-optimization history pairing and reject non-finite candidates #129 blocker

@Michele-Martini, could you please review the physical scale selection and the intended regeneration sequencing?

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Section V.d collocated gain-optimization script to use a physically interpretable integral-error saturation scale (tendon-length error in meters) instead of a fixed, opaque gamma constant, and documents that the currently committed Section V.d artifacts are now stale.

Changes:

  • Replace the collocated optimizer’s fixed gamma=10 with gamma = 1 / e_sat using a default e_sat = 0.01 m.
  • Add --integral-error-saturation-scale CLI option with validation for finite, strictly positive values.
  • Document the derivation/scale selection and mark committed Section V.d MAT/plots as stale in the case README.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
paper_results/secVd_control_gain_optimization/README.md Adds a prominent stale-artifacts warning and documents the tendon-scale saturation rationale and usage.
paper_results/secVd_control_gain_optimization/code/control_gain_optimization_with_collocated.py Introduces a configurable tendon-length saturation scale, validates it, and computes gamma as its reciprocal for PID tanh saturation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings August 3, 2026 02:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (1)

paper_results/secVd_control_gain_optimization/code/control_gain_optimization_with_collocated.py:266

  • After validating --integral-error-saturation-scale itself, tendon_error_gamma = 1.0 / tendon_error_saturation_scale can still overflow to a non-finite value for extremely small but positive (subnormal) scales. That failure would currently surface later as a PIDControl "Gamma must be finite" error, which is less actionable for CLI users. Consider validating that the computed tendon_error_gamma is finite and raising a ValueError that points back to the CLI flag.
tendon_error_saturation_scale = ARGS.integral_error_saturation_scale  # [m]
tendon_error_gamma = 1.0 / tendon_error_saturation_scale  # [1/m]

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.

2 participants