Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduction of Barriers, Position barrier #87

Merged
merged 108 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from 107 commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
1395d56
feat: barrier init
domrachev03 May 2, 2024
522bfdd
feat: position barrier init
domrachev03 May 2, 2024
15fc97f
feat: configuration (joint) barrier
domrachev03 May 3, 2024
72e3035
refactor: leading whitespace in barriers folder
domrachev03 May 3, 2024
04202e6
feat: add barriers support to solve_ik.py
domrachev03 May 3, 2024
859e4d5
fix: solve_ik compatability fixes
domrachev03 May 3, 2024
44e919d
fix: minor code debug and refactoring
domrachev03 May 3, 2024
7a24e9a
feat: updating safe policy in barrier
domrachev03 May 3, 2024
1c82bb5
example: ur5 with cbf init
domrachev03 May 3, 2024
01491fa
feat: compute_save_policy abstract method
domrachev03 May 4, 2024
043c590
example: copy shapes file to cbf folder
domrachev03 May 4, 2024
ba3f0dc
fix: remove dt term from cost (because other terms does not use it)
domrachev03 May 4, 2024
e0f74e2
example: the best cbf behaviour yet
domrachev03 May 5, 2024
5534c8f
feat: update solve_ik
domrachev03 May 5, 2024
cdc3b80
fix: refactor compute_qp_objective in barrier.py
domrachev03 May 5, 2024
17872fb
fix: transfering position jacobian from local to world aligned frame
domrachev03 May 6, 2024
a7e6f67
fix: isinstance for gain
domrachev03 May 6, 2024
964e81e
fix: remove debugging print
domrachev03 May 6, 2024
40d2b19
fix: configuration barrier fix
domrachev03 May 6, 2024
0d13b08
feat: optional disabling of position limits
domrachev03 May 6, 2024
9cba01c
example: add position CBF to ur5 example
domrachev03 May 6, 2024
197c22b
fix: remove mask variable from position barrier as redundant
domrachev03 May 6, 2024
7998520
feat: body spherical self-collision barrier
domrachev03 May 6, 2024
8948015
example: yumi example
domrachev03 May 6, 2024
0f94a6c
feat: full self-collision barrier init
domrachev03 May 9, 2024
472e78b
example: baxter example
domrachev03 May 9, 2024
1b22d8a
revert: remove hpp-fcl self-collision code (moved to separate branch)
domrachev03 May 10, 2024
63b7963
refactor: ruff format
domrachev03 May 10, 2024
985acb1
CICD: create pipeline for building gh pages from feat/cbf branch
domrachev03 May 10, 2024
e61d44c
docs: add barriers to documentation
domrachev03 May 10, 2024
a5803d1
docs: fix documentation
domrachev03 May 10, 2024
2a2fa25
docs: yet another attempt to fix documentation
domrachev03 May 10, 2024
4a45d48
docs: kill me
domrachev03 May 10, 2024
5859354
feat: shift point for spherical body collision avoidance barrier
domrachev03 May 10, 2024
0ef506f
chore: add sphere object in meshcat shapes
domrachev03 May 10, 2024
b85f352
example: adapt yumi example for shifted collision sphere origin
domrachev03 May 10, 2024
e876f35
docstrings and notes
simeon-ned May 11, 2024
0287f34
example: yumi example with creating new frames
domrachev03 May 11, 2024
22798c8
Revert "feat: shift point for spherical body collision avoidance barr…
domrachev03 May 11, 2024
b839445
new doc strings
simeon-ned May 11, 2024
573c8f3
Merge remote-tracking branch 'refs/remotes/origin/feat/cbf' into feat…
domrachev03 May 11, 2024
60089e0
refactor: CBF -> Barrier in names
domrachev03 May 11, 2024
05c3770
docs: fix documentation
domrachev03 May 11, 2024
105e43c
fix: remove temporary file from git
domrachev03 May 11, 2024
5cd638f
refactor: examples/cbfs -> examples/barriers
domrachev03 May 11, 2024
5a27be2
modified spherical barrier
simeon-ned May 11, 2024
e8254f6
Merge branch 'feat/cbf' of github.com:domrachev03/pink into feat/cbf
simeon-ned May 11, 2024
36363d5
fixed typo in docs
simeon-ned May 11, 2024
2d9eddb
refactor: frame -> frames in BodySphericalBarrier
domrachev03 May 11, 2024
20b2ab6
example: ipynb with theory and main results
domrachev03 May 11, 2024
9aac262
Merge remote-tracking branch 'refs/remotes/origin/feat/cbf' into feat…
domrachev03 May 11, 2024
9e1cf96
feat: argumant to optionally not open visualization
domrachev03 May 11, 2024
8636ecc
example: disable running simulation in browser in ipynb example
domrachev03 May 11, 2024
820059d
chore: update changelog.md
domrachev03 May 11, 2024
80259a9
refactor: tuple -> Tuple for version compatibility
domrachev03 May 11, 2024
9a2f657
refactor: refactoring for pipeline
domrachev03 May 11, 2024
f75d5b1
refactor: mypy types fixes
domrachev03 May 11, 2024
e9d53cb
refactor: attempt to fix documentation pipeline
domrachev03 May 11, 2024
08dad1b
changed examples, renamed cbfs to barriers
simeon-ned May 12, 2024
a9a0373
example: fix & beautify barrier examples
domrachev03 May 12, 2024
a1940ea
fix: relaxing constraints in yumi example
domrachev03 May 12, 2024
1f94b75
added references and videos
simeon-ned May 12, 2024
426e5e1
fixed references
simeon-ned May 12, 2024
8be9307
Merge pull request #1 from domrachev03/feat/cbf
domrachev03 May 12, 2024
39c428b
Merge branch 'stephane-caron:main' into main
domrachev03 May 12, 2024
d4d9199
chore: remove assets folder and prepare README.md for inserting video…
domrachev03 May 12, 2024
92220db
Update examples/barriers/README.md
domrachev03 May 12, 2024
454fdcb
Update examples/barriers/README.md
domrachev03 May 12, 2024
a481455
fixed floating base, go2 example
simeon-ned May 15, 2024
350e7c6
fixed floating base, go2 example
simeon-ned May 15, 2024
e8b8354
Update README.md
simeon-ned May 15, 2024
c6ab5b4
Added video to README.md
simeon-ned May 15, 2024
88a39e4
Fixed video README.md
simeon-ned May 15, 2024
347d9f2
refactor: autorefacroting
domrachev03 May 15, 2024
5dad421
fix: p_min and p_max simultaneously in position barrier
domrachev03 May 15, 2024
750336f
Merge pull request #2 from domrachev03/fix/hessian_nq
simeon-ned May 15, 2024
5d8e948
remove all functionality unrelated to PR
domrachev03 May 15, 2024
2df8b43
feat: add exception for no limit provided
domrachev03 May 15, 2024
0275f34
fix: default radius is changed to 0
domrachev03 May 15, 2024
d4aafc1
fix: proper position gain update
domrachev03 May 15, 2024
0559fd1
fix: barrier representation
domrachev03 May 15, 2024
65e3348
tests: unit tests for barrier and position barrier
domrachev03 May 15, 2024
f36c6d8
test: modify general barrier tests and add solve_ik tests with barriers
domrachev03 May 15, 2024
71db291
docs: tests docstrings
domrachev03 May 15, 2024
490891a
fix: remove & change files for PR
domrachev03 May 16, 2024
f8b01cb
fix: adapt changelog and revert changes in visualization.py
domrachev03 May 16, 2024
b9f9f16
Chore: GO2 -> Go2
domrachev03 May 18, 2024
3415bb8
refactor: refactor examples
domrachev03 May 18, 2024
b82c7da
refactor: additional examples refactor
domrachev03 May 18, 2024
a82e1b0
chore: copyright information in barriers init
domrachev03 May 18, 2024
7270aba
chore: copyright information & documentation fix
domrachev03 May 18, 2024
35a5176
Reference to class kappa function
domrachev03 May 18, 2024
506e82b
refactor: class_k_fn -> gain_function
domrachev03 May 18, 2024
ca38717
chore: remove noqa tags
domrachev03 May 18, 2024
9c62d82
refactor: rename & rewrite safe_policy as safe_displacement
domrachev03 May 18, 2024
6354e26
chore: remove information about new version from changelog.md
domrachev03 May 18, 2024
0d0a3b4
refactor: update __repr__ method of barrier
domrachev03 May 18, 2024
862de35
test: update barrier representation test
domrachev03 May 18, 2024
d691964
refactor: pos_jac -> pos_jacobian_in_frame/world
domrachev03 May 18, 2024
b16f34c
fix: wrong multiplier in barriers cost
domrachev03 May 23, 2024
85625c7
example: relax ur5 example to avoid configuration error
domrachev03 May 23, 2024
aa3f242
fix: docstring fix
domrachev03 May 23, 2024
9c2eaa0
refactor: autorefactoring
domrachev03 May 23, 2024
7644548
chore: add link to CBF theory
domrachev03 May 27, 2024
db859bf
refactor: documentation fix
domrachev03 May 27, 2024
3229ca2
Merge branch 'pr/position_barrier' of https://github.com/domrachev03/…
domrachev03 May 27, 2024
82a28d7
refactor: autorefactoring
domrachev03 May 27, 2024
27bd793
fix: adding minus to c term in barrier objective
domrachev03 May 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@
All notable changes to this project will be documented in this file.

## Unreleased

### Added
- Control Barrier Functions, namely:
- Abstract Barrier ``Barrier``
- Frame Position Barrier ``PositionBarrier``
- Examples for `UR5` manipulator and `go2` quadruped robot, which illustrate barriers effect.

### Changed

- CICD: Update ruff to 0.4.3
- Configuration accepts list of Control Barrier Functions

### Fixed

Expand Down
16 changes: 16 additions & 0 deletions doc/barriers.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
:github_url: https://github.com/stephane-caron/pink/tree/main/doc/barriers.rst

.. _Barriers:

********
Barriers
********

.. automodule:: pink.barriers
:members:

Position Barrier
=================

.. automodule:: pink.barriers.position_barrier
:members:
2 changes: 2 additions & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Inverse kinematics in Pink is defined by weighted :ref:`tasks <Tasks>` and :ref:
introduction.rst
tasks.rst
limits.rst
barriers.rst
inverse-kinematics.rst
developer-notes.rst
references.rst

48 changes: 48 additions & 0 deletions examples/barriers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
Here we will have the examples of using barriers, please go over [notes](https://simeon-ned.com/blog/2024/cbf/) for more info.

# Barrier Examples


- [Arm: UR5](#arm-ur5): with joints and end effector limits
- [Quadruped: Go2](#go2-squat): Go 2 squatting with floating base position limits
- [Dual Arms: Yumi](#dual-arm-yumi): self collisions with spheres

## Arm UR5

A UR5 arm tracking a moving target while stopping in front of virtual wall:


https://github.com/domrachev03/pink/assets/28687492/f30ba7a1-98a3-44cb-ab52-23f99e42714c


| Task | Cost |
|------|------|
| End-effector | (50,1) |
| Posture | $10^{-3}$ |

| Barrier | Gain |
|------|------|
| End-effector | $10^{2}$ |

## Go2 squat

Go2 quadruped squating with base position is constrained by z and y coordinates:

https://github.com/domrachev03/pink/assets/26837717/701bdfbe-0dba-4f9d-80e2-c018475f38d6



| Task | Cost |
|------|------|
| Base | (50, 1) |
| Legs | 200 |
| Posture | $10^{-3}$ |

| Barrier | Gain |
|------|------|
| End-effector | $10^{2}$ |



stephane-caron marked this conversation as resolved.
Show resolved Hide resolved


117 changes: 117 additions & 0 deletions examples/barriers/arm_ur5.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# SPDX-License-Identifier: Apache-2.0
# Copyright 2024 Stéphane Caron, Ivan Domrachev, Simeon Nedelchev

"""Universal Robots UR5 arm tracking a moving target."""

import meshcat_shapes
import numpy as np
import qpsolvers
from loop_rate_limiters import RateLimiter

import pink
from pink import solve_ik
from pink.barriers import PositionBarrier
from pink.tasks import FrameTask, PostureTask
from pink.visualization import start_meshcat_visualizer

try:
from robot_descriptions.loaders.pinocchio import load_robot_description
except ModuleNotFoundError as exc:
raise ModuleNotFoundError(
"Examples need robot_descriptions, "
"try ``pip install robot_descriptions``"
) from exc # noqa: E501


if __name__ == "__main__":
robot = load_robot_description("ur5_description", root_joint=None)
viz = start_meshcat_visualizer(robot)

end_effector_task = FrameTask(
"ee_link",
position_cost=10.0, # [cost] / [m]
orientation_cost=1.0, # [cost] / [rad]
)

posture_task = PostureTask(
cost=1e-3, # [cost] / [rad]
)

pos_barrier = PositionBarrier(
"ee_link",
indices=[1],
p_min=np.array([-0.4]),
p_max=np.array([0.6]),
gain=np.array([100.0]),
safe_displacement_gain=1.0,
)
barriers = [pos_barrier]

tasks = [end_effector_task, posture_task]

q_ref = np.array(
[
1.27153374,
-0.87988708,
1.89104795,
1.73996951,
-0.24610945,
-0.74979019,
]
)
configuration = pink.Configuration(robot.model, robot.data, q_ref)
for task in tasks:
task.set_target_from_configuration(configuration)
viz.display(configuration.q)

viewer = viz.viewer
meshcat_shapes.frame(viewer["end_effector_target"], opacity=0.5)
meshcat_shapes.frame(viewer["end_effector"], opacity=1.0)

# Select QP solver
solver = qpsolvers.available_solvers[0]
if "osqp" in qpsolvers.available_solvers:
solver = "osqp"

rate = RateLimiter(frequency=200.0)
dt = rate.period
t = 0.0 # [s]
while True:
# Update task targets
end_effector_target = end_effector_task.transform_target_to_world
end_effector_target.translation[1] = 0.0 + 0.65 * np.sin(t / 4)
end_effector_target.translation[2] = 0.5

# Update visualization frames
viewer["end_effector_target"].set_transform(end_effector_target.np)
viewer["end_effector"].set_transform(
configuration.get_transform_frame_to_world(
end_effector_task.frame
).np
)

velocity = solve_ik(
configuration,
tasks,
dt,
solver=solver,
barriers=barriers,
)
configuration.integrate_inplace(velocity, dt)

G, h = pos_barrier.compute_qp_inequality(configuration, dt=dt)
print(f"Task error: {end_effector_task.compute_error(configuration)}")
print(
f"Position CBF value: {pos_barrier.compute_barrier(configuration)[0]:0.3f} >= 0"
)
print(
f"""Distance to manipulator: {configuration.get_transform_frame_to_world('ee_link').translation[1]} <= 0.6"""
)
print("-" * 60)
# Visualize result at fixed FPS
viz.display(configuration.q)
rate.sleep()
t += dt
137 changes: 137 additions & 0 deletions examples/barriers/go2_squat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# SPDX-License-Identifier: Apache-2.0
# Copyright 2024 Stéphane Caron, Ivan Domrachev, Simeon Nedelchev

"""Go2 squat with z-axis barrier."""

import meshcat_shapes
import numpy as np
import qpsolvers
from loop_rate_limiters import RateLimiter
import pinocchio as pin

import pink
from pink import solve_ik
from pink.barriers import PositionBarrier
from pink.tasks import FrameTask, PostureTask
from pink.visualization import start_meshcat_visualizer

try:
from robot_descriptions.loaders.pinocchio import load_robot_description
except ModuleNotFoundError as exc:
raise ModuleNotFoundError(
"Examples need robot_descriptions, "
"try ``pip install robot_descriptions``"
) from exc # noqa: E501


if __name__ == "__main__":
robot = load_robot_description(
"go2_description", root_joint=pin.JointModelFreeFlyer()
)
viz = start_meshcat_visualizer(robot)

q_ref = np.array(
[
-0.0,
0.0,
0.3,
0.0,
0.0,
0.0,
1.0,
0.0,
0.8,
-1.57,
0.0,
0.8,
-1.57,
0.0,
0.8,
-1.57,
0.0,
0.8,
-1.57,
]
)

configuration = pink.Configuration(robot.model, robot.data, q_ref)

base_task = FrameTask(
"base",
position_cost=50.0, # [cost] / [m]
orientation_cost=1.0, # [cost] / [rad]
)

posture_task = PostureTask(
cost=1e-5, # [cost] / [rad]
)

pos_barrier = PositionBarrier(
"base",
indices=[1, 2],
p_max=np.array([0, 0.35]),
gain=np.array([100.0, 100.0]),
safe_displacement_gain=1.0,
)
barriers = [pos_barrier]

tasks = [base_task, posture_task]

for foot in ["FL_foot", "FR_foot", "RL_foot", "RR_foot"]:
task = FrameTask(
foot,
position_cost=200.0, # [cost] / [m]
orientation_cost=0.0, # [cost] / [rad]
)
tasks.append(task)

for task in tasks:
task.set_target_from_configuration(configuration)

viewer = viz.viewer
opacity = 0.5 # Set the desired opacity level (0 transparent, 1 opaque)

meshcat_shapes.frame(viewer["base_target"], opacity=1.0)
meshcat_shapes.frame(viewer["base"], opacity=1.0)

# Select QP solver
solver = qpsolvers.available_solvers[0]
if "osqp" in qpsolvers.available_solvers:
solver = "osqp"

rate = RateLimiter(frequency=200.0)
dt = rate.period
t = 0.0 # [s]
period = 4
omega = 2 * np.pi / period
while True:
# Update task targets
end_effector_target = base_task.transform_target_to_world
phase = (t // period) % 2
Ay = 0.1 * (1 - phase)
Az = 0.2 * phase

end_effector_target.translation[1] = 0.0 + Ay * np.sin(omega * t)
end_effector_target.translation[2] = 0.3 + Az * np.sin(omega * t)

# Update visualization frames
viewer["base_target"].set_transform(end_effector_target.np)
viewer["base"].set_transform(
configuration.get_transform_frame_to_world(base_task.frame).np
)

velocity = solve_ik(
configuration,
tasks,
dt,
solver=solver,
barriers=barriers,
)
configuration.integrate_inplace(velocity, dt)

viz.display(configuration.q)
rate.sleep()
t += dt
Loading
Loading