Skip to content

[BREAKING] fix and update: holonomic constraint biais was wrong.#1044

Merged
pariterre merged 27 commits intopyomeca:masterfrom
Ipuch:master
Feb 9, 2026
Merged

[BREAKING] fix and update: holonomic constraint biais was wrong.#1044
pariterre merged 27 commits intopyomeca:masterfrom
Ipuch:master

Conversation

@Ipuch
Copy link
Collaborator

@Ipuch Ipuch commented Feb 5, 2026

Pull Request Checklist

All Submissions:

  • Have you followed the guidelines in our Contributing document [docs/contribution.md]?
  • Have you checked to ensure there aren't other open [Pull Requests] for the same update/change?
  • Have you opened/linked the issue related to your pull request?
  • Have you used the tag [WIP] for on-going changes, and removed it when the pull request was ready?
  • When ready to merge, have you sent a comment pinging @pariterre in it?

New Feature Submissions:

  1. Does your submission pass the tests (if not please explain why this is intended)?
  2. Did you write a proper documentation (docstrings and ReadMe)
  3. Have you linted your code locally prior to submission (using the command: black . -l120 --exclude "external/*")?

Changes to Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new examples for your core changes, as applicable?
  • Have you written new tests for your core changes, as applicable?

Summary

Renames French "biais" to English "bias" throughout the holonomic constraints module. Also fixes a bug in rigid contact dynamics and cleans up examples.


⚠️ Breaking Change

Migration: Replace biaisbias in your code:

  • biais_vector()bias_vector()
  • _holonomic_constraints_biais_holonomic_constraints_bias
  • compute_biais_vector()compute_bias_vector()

Changes

1. API Rename (biais → bias)

Before After File
_holonomic_constraints_biais _holonomic_constraints_bias holonomic_biorbd_model.py
biais_vector() bias_vector() holonomic_biomodel.py
compute_biais_vector() compute_bias_vector() holonomic_constraints.py

2. API Change: Holonomic Constraint Return Values

The third return value of HolonomicConstraintsFcn methods is now a bias function (J̇q̇) instead of an acceleration constraint function. Users must compute the full acceleration constraint manually:

# Before (wrong - treated 3rd value as acceleration function):
_, _, acceleration_constraint_func = HolonomicConstraintsFcn.rigid_contacts(model)
defect = acceleration_constraint_func(q, qdot, qddot, params)

# After (correct - 3rd value is bias, compute Φ̈ = J·q̈ + J̇·q̇):
_, jacobian, bias = HolonomicConstraintsFcn.rigid_contacts(model)
defect = jacobian(q, params) @ qddot + bias(q, qdot, params)

Affected methods: superimpose_markers(), align_frames(), rigid_contacts()

3. Test Refactoring

  • test_biorbd_model_holonomic.py: Major cleanup (−1,310 / +1,027 lines)
  • test_vector_layout.py: Updated bias reference

4. Code Cleanup

  • Deleted unused common.py
  • Cleaned 10 holonomic examples (duplicate imports, typos, docstrings)

Review Focus

  1. API rename complete? Verify all biaisbias replacements
  2. Bias function usage correct? Check that constraint acceleration is computed as J·q̈ + bias
  3. Test coverage maintained? Review refactored tests

Import Issue Fixes

Problem: Examples using custom_dynamics.py failed when imported by tests with ModuleNotFoundError: No module named 'custom_dynamics'

Solution: Implemented try/except pattern for relative imports with fallback:

try:
    from .custom_dynamics import ModifiedHolonomicTorqueBiorbdModel
except ImportError:
    from custom_dynamics import ModifiedHolonomicTorqueBiorbdModel

Files Fixed:

  • two_pendulums_algebraic.py
  • arm26_pendulum_swingup_muscle.py
  • arm26_pendulum_swingup_muscle_algebraic.py

Test Expectations Updated

Problem: Test failures due to numerical changes in compute_q_from_u_iterative implementation

Solution: Updated expected values in test_biorbd_model_holonomic.py for:

  • test_example_three_bar
  • test_example_four_bar
  • test_example_two_pendulums_2constraint
  • test_example_two_pendulums_rotule
  • test_example_arm26_pendulum_swingup

All tests now pass with the new implementation.

Code Quality Improvements

Fixed in 10+ example files:

  • ✅ Removed duplicate import numpy as np statements
  • ✅ Fixed typos: "two single pendulum" → "two single pendulums", "variaibles" → "variables"
  • ✅ Removed commented-out code blocks
  • ✅ Improved docstrings with accurate descriptions
  • ✅ Added proper method documentation headers

Files Cleaned:

  • two_pendulums.py
  • two_pendulums_algebraic.py
  • three_bar.py
  • four_bar.py
  • two_pendulums_2constraint.py
  • two_pendulums_2constraint_4DOF.py
  • two_pendulums_rotule.py
  • arm26_pendulum_swingup.py
  • arm26_pendulum_swingup_muscle.py
  • arm26_pendulum_swingup_muscle_algebraic.py

Documentation Enhancements

Module Documentation (holonomic_constraints.py):

  • Enhanced module-level docstring with comprehensive overview
  • Improved class docstrings for HolonomicConstraintsFcn and HolonomicConstraintsList
  • Added detailed method documentation with Parameters, Returns, Notes, See Also, and References sections
  • Clarified the mathematical formulation (Φ(q) = 0, Jacobian, bias terms)

Example Docstrings:

  • Updated all example docstrings with accurate problem descriptions
  • Added proper explanation of model features (holonomic constraints, algebraic states, etc.)
  • Improved consistency across all holonomic constraint examples

This change is Reviewable

@Ipuch Ipuch added the bug Something isn't working label Feb 5, 2026
@Ipuch Ipuch changed the title fix and update: holonomic constraint biais was wrong. [RTR] fix and update: holonomic constraint biais was wrong. Feb 6, 2026
black = 26.1
@Ipuch
Copy link
Collaborator Author

Ipuch commented Feb 6, 2026

@EveCharbie Could you please at least review the rigid contact defect consequences. Tell me if you have time to review the rest. Otherwise @pariterre.

Please note there is a lot of doc and example clean up, and test values update, which explains the big amount of lines. Stay focus on the bioptim core first, instead of examples and tests.

@p-shg consider reviewing the changes too, to prepare and update of your branch in #1042. (@fbailly )

@codecov
Copy link

codecov bot commented Feb 6, 2026

Codecov Report

❌ Patch coverage is 31.97674% with 117 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.94%. Comparing base (3ab61ce) to head (6cc24c3).
⚠️ Report is 29 commits behind head on master.

Files with missing lines Patch % Lines
bioptim/models/biorbd/holonomic_biorbd_model.py 23.61% 55 Missing ⚠️
bioptim/models/protocols/holonomic_constraints.py 37.50% 25 Missing ⚠️
...traints/arm26_pendulum_swingup_muscle_algebraic.py 50.00% 8 Missing ⚠️
...nomic_constraints/arm26_pendulum_swingup_muscle.py 56.25% 7 Missing ⚠️
...oy_examples/holonomic_constraints/two_pendulums.py 0.00% 6 Missing ⚠️
...s/holonomic_constraints/two_pendulums_algebraic.py 42.85% 4 Missing ⚠️
...es/holonomic_constraints/arm26_pendulum_swingup.py 0.00% 2 Missing ⚠️
...les/toy_examples/holonomic_constraints/four_bar.py 0.00% 2 Missing ⚠️
...es/toy_examples/holonomic_constraints/three_bar.py 0.00% 2 Missing ⚠️
...holonomic_constraints/two_pendulums_2constraint.py 0.00% 2 Missing ⚠️
... and 2 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1044      +/-   ##
==========================================
- Coverage   77.15%   76.94%   -0.22%     
==========================================
  Files         193      192       -1     
  Lines       21019    21071      +52     
==========================================
- Hits        16218    16213       -5     
- Misses       4801     4858      +57     
Flag Coverage Δ
unittests 76.94% <31.97%> (-0.22%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@EveCharbie
Copy link
Collaborator

  1. As long as the results from the test "test_contact_forces_inverse_dynamics_constraint_muscle" do not change for any of the implicit configurations, it is fine with me :)

  2. Do you understand why the previous version worked ?

  3. I reviewed the code (not the math) quickly and everything seems good to me. Ideally, just increase test coverage so that we do not break this in the future (especially since the math is complicated !).

@Ipuch
Copy link
Collaborator Author

Ipuch commented Feb 6, 2026

  1. I don't know if there is a test for your contact implicit inverse dynamic problem because it just doesn't crash on my side, but I would have expected it to crash. The only thing that crashed is the way the acceleration constraint was written. So if the acceleration constraint was included in your problem, then the coverage of the OCP is not well defined. Please help me out.

  2. Yes, it was working because we were enforcing the constraint to remain at 0 every time. But it didn't affect the Lagrange multipliers and the acceleration of the system because it didn't affect the way the equations of motion are written in its partitioned way.

Okay, don't you have any advice on the code smells that I could have done?

@pariterre
Copy link
Member

Should we merge #1045 before merging here?

Copy link
Member

@pariterre pariterre left a comment

Choose a reason for hiding this comment

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

That is really satisfying to see all the clean up!
Thanks!

@pariterre reviewed 29 files and all commit messages, and made 3 comments.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @Ipuch).


bioptim/examples/toy_examples/holonomic_constraints/arm26_pendulum_swingup_muscle_algebraic.py line 210 at r1 (raw file):

if __name__ == "__main__":
    main()
    main()

two mains?


bioptim/examples/toy_examples/holonomic_constraints/arm26_pendulum_swingup_muscle.py line 42 at r1 (raw file):

    from .custom_dynamics import HolonomicMusclesBiorbdModel
except ImportError:
    from custom_dynamics import HolonomicMusclesBiorbdModel

This should not be mandatory... Have you tried adding a "init.py" file in the current folder?
or to move "custom_dynamics.py" in a "custom_dynamics" folder and put the code in "init.py" in that folder?

Copy link
Collaborator Author

@Ipuch Ipuch left a comment

Choose a reason for hiding this comment

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

@Ipuch made 2 comments.
Reviewable status: 27 of 29 files reviewed, 2 unresolved discussions (waiting on @pariterre).


bioptim/examples/toy_examples/holonomic_constraints/arm26_pendulum_swingup_muscle.py line 42 at r1 (raw file):

Previously, pariterre (Pariterre) wrote…

This should not be mandatory... Have you tried adding a "init.py" file in the current folder?
or to move "custom_dynamics.py" in a "custom_dynamics" folder and put the code in "init.py" in that folder?

it didnot work


bioptim/examples/toy_examples/holonomic_constraints/arm26_pendulum_swingup_muscle_algebraic.py line 210 at r1 (raw file):

Previously, pariterre (Pariterre) wrote…

two mains?

done

@Ipuch
Copy link
Collaborator Author

Ipuch commented Feb 9, 2026

@pariterre RTM for me.

Copy link
Member

@pariterre pariterre left a comment

Choose a reason for hiding this comment

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

@pariterre reviewed 12 files and all commit messages, and resolved 2 discussions.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @Ipuch).

@pariterre pariterre changed the title [RTR] fix and update: holonomic constraint biais was wrong. [BREAKING] fix and update: holonomic constraint biais was wrong. Feb 9, 2026
@pariterre pariterre merged commit f31b093 into pyomeca:master Feb 9, 2026
22 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants