Skip to content

Enhance impedance control#79

Open
nickswalker wants to merge 24 commits into
TimSchneider42:masterfrom
nickswalker:enhance-impedance-control
Open

Enhance impedance control#79
nickswalker wants to merge 24 commits into
TimSchneider42:masterfrom
nickswalker:enhance-impedance-control

Conversation

@nickswalker
Copy link
Copy Markdown
Contributor

Expand the impedance motion stack for both joint-space and Cartesian torque control. Adds tracking/reference-handle based impedance motions, introduces nullspace posture control for Cartesian impedance, adds joint-limit repulsion and shared torque safety utilities, and updates the Python API and docs accordingly.

  • Add joint impedance motions with joint-limit repulsion.
  • Add joint impedance tracking via live reference updates.
  • Refactor the Cartesian impedance API and rename the base class from ImpedanceMotion to CartesianImpedanceBase, now that there is a distinct JointImpedanceMotion class
  • Add tracking/moving Cartesian references for impedance control.
  • Move target_type into fixed-target Cartesian impedance motions.
  • Add Cartesian nullspace posture control.
  • Apply the same joint-limit repulsion model to Cartesian impedance.
  • Expand README/API docs for the impedance motion interfaces.
    • At present, the ImpedanceMotion types aren't discussed at all in the readme.

Opening to see if anyone has feedback. I'll add some Python examples and share some videos later in this thread.

@TimSchneider42
Copy link
Copy Markdown
Owner

Hi,

I think this PR adds some really important functionality, but I will need some time to review it. I will get back to you once I have taken a look at it. Thank you very much for the PR, though!

Best,
Tim

@nickswalker
Copy link
Copy Markdown
Contributor Author

nickswalker commented Mar 28, 2026

Thanks for your willingness to take a look! Here are the two new Python examples running on an FR3.

manual_guidance_joint_impedance.py demonstrates setting joint 6 to be very stiff while leaving the others compliant (a la franka_interactive_controllers), which can sometimes be useful when doing kinesthetic teaching

trim.B82E2E43-2B00-4CC8-8B18-B52AE9AD1165.MOV

cartesian_virtual_fixture.py demonstrates a Python-side loop updating the cartesian reference for the cartesian impedance controller, allowing the user to push the robot along a vertical axis, and resisting all other motion.

trim.247AD8D4-340B-481A-AF0C-A6783A8653C9.MOV

@nickswalker nickswalker force-pushed the enhance-impedance-control branch from f0e71ab to e776619 Compare March 28, 2026 01:12
@nickswalker nickswalker marked this pull request as ready for review March 28, 2026 01:13
@Asunatan
Copy link
Copy Markdown

Hello, thank you for sharing this work—the impedance control shown in the video looks very smooth and promising.

I'm relatively new to robotics and have been evaluating open-source Python libraries for controlling the Franka Emika Panda. Currently, I'm using Deoxys, but I've observed noticeable jitter when performing impedance control, which affects trajectory tracking and force adjustment. I've also looked at FrankaPy, but it doesn't seem to provide a dedicated impedance control interface. Given the performance your library demonstrates, I'm very much looking forward to it…

@Brunch-Life
Copy link
Copy Markdown

It's quite a good feature! I'm using it to use gello control franka use joint implance control!

@Brunch-Life
Copy link
Copy Markdown

waiting for this to be approved!

@nickswalker
Copy link
Copy Markdown
Contributor Author

I set the fork to compile and release wheels in the meantime: https://github.com/nickswalker/franky/releases
Also added 0.21.1 libfranka builds, as those are what the videos were recorded with.

@TimSchneider42
Copy link
Copy Markdown
Owner

Hey guys,

Sorry for the delay in merging this. I am currently super busy as I am pushing for NeurIPS (deadline is on the 6th of May). I cannot promise to merge this before the deadline, as I would like to review it thoroughly. However, I will try my best to do it as soon as I can.

Best,
Tim

Add JointImpedanceTrackingMotion and CartesianImpedanceTrackingMotion
Rename the Cartesian shared base to CartesianImpedanceBase and keep ImpedanceMotion as an alias
Extend CartesianImpedanceBase update method with abs_time so it can be passed to
whoever is calculating the dynamic reference
Add twist to reference types
Without twist, behavior remains as was before
With twist, damping only applies to motion that doesn't match the reference twist
Keep target_type on the Cartesian motions that actually interpret a one-time pose target, instead of on the shared impedance base
Way too easy to trip the joint velocity limits by pushing
the robot close to a joint limit. Any action the cartesian
controller was taking would violate the limit
Factor out joint limit repulsion params from joint impedance
motion
Add saturation to cartesian impedance controller
Use same double-buffered strategy to expose to python
Exponentially interpolate gains
An extra backstop against big reference changes
causing torque to explode
@nickswalker nickswalker force-pushed the enhance-impedance-control branch from 55a9773 to f168fd3 Compare April 17, 2026 03:34
Negative values could cause the controller to explode
Default to reasonable new damping when updating stiffness from Tracker
@nickswalker nickswalker force-pushed the enhance-impedance-control branch from f168fd3 to 46852c7 Compare April 17, 2026 03:36
@hugohadfield
Copy link
Copy Markdown

Really looking forward to seeing this land!

Brunch-Life added a commit to Brunch-Life/franky that referenced this pull request May 13, 2026
The fork's release_wheels workflow produces a wheel with the same
file name and version (1.1.3) as the upstream franky-control on PyPI.
When users run `pip install --find-links <fork release> franky-control`,
pip sees both sources and may pick the upstream PyPI wheel -- which is
missing the enhance-impedance-control changes (PR TimSchneider42#79).

Patch VERSION in CI to '1.1.3+impedance.libfranka.<ver>' so the
produced wheel carries a PEP 440 local-version label that does not
exist on PyPI. pip then prefers the local-label wheel from this
fork unambiguously.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Brunch-Life <brunchlife@hotmail.com>
Brunch-Life added a commit to Brunch-Life/franky that referenced this pull request May 13, 2026
The fork's release_wheels workflow produces a wheel with the same
file name and version (1.1.3) as the upstream franky-control on PyPI.
When users run `pip install --find-links <fork release> franky-control`,
pip sees both sources and may pick the upstream PyPI wheel -- which is
missing the enhance-impedance-control changes (PR TimSchneider42#79).

Patch VERSION in CI to '1.1.3+impedance.libfranka.<ver>' so the
produced wheel carries a PEP 440 local-version label that does not
exist on PyPI. pip then prefers the local-label wheel from this
fork unambiguously.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Brunch-Life <brunchlife@hotmail.com>
nickswalker pushed a commit to nickswalker/franky that referenced this pull request May 13, 2026
The fork's release_wheels workflow produces a wheel with the same
file name and version (1.1.3) as the upstream franky-control on PyPI.
When users run `pip install --find-links <fork release> franky-control`,
pip sees both sources and may pick the upstream PyPI wheel -- which is
missing the enhance-impedance-control changes (PR TimSchneider42#79).

Patch VERSION in CI to '1.1.3+impedance.libfranka.<ver>' so the
produced wheel carries a PEP 440 local-version label that does not
exist on PyPI. pip then prefers the local-label wheel from this
fork unambiguously.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Brunch-Life <brunchlife@hotmail.com>
@TimSchneider42
Copy link
Copy Markdown
Owner

Sorry to keep you waiting for so long. I will have some time next week to review the code and merge the PR.

Use std::optional for joint lower/upper limits, and force constraints. Simplifies construction
nickswalker pushed a commit to nickswalker/franky that referenced this pull request May 23, 2026
The fork's release_wheels workflow produces a wheel with the same
file name and version (1.1.3) as the upstream franky-control on PyPI.
When users run `pip install --find-links <fork release> franky-control`,
pip sees both sources and may pick the upstream PyPI wheel -- which is
missing the enhance-impedance-control changes (PR TimSchneider42#79).

Patch VERSION in CI to '1.1.3+impedance.libfranka.<ver>' so the
produced wheel carries a PEP 440 local-version label that does not
exist on PyPI. pip then prefers the local-label wheel from this
fork unambiguously.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Brunch-Life <brunchlife@hotmail.com>
YuqianJiang and others added 5 commits May 24, 2026 23:49
Use composition instead of inheritance for safety param struct
Reasonable defaults for per-joint max friction instead of 0s. Actual friction params still default to 0
Pull correct joint bounds based on robot type
@nickswalker nickswalker force-pushed the enhance-impedance-control branch from cdc7abb to 5b433be Compare May 25, 2026 03:55
@nickswalker
Copy link
Copy Markdown
Contributor Author

We've been using the JointImpedenceTracker in 0 stiffness for collecting kinesthetic demonstrations lately and noticed that the joints aren't quite transparent. Went ahead and incorporated a simple friction compensation feedforward term (off by default), as I expect this will be a common use case.

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.

6 participants