Skip to content

Commit df5edf7

Browse files
authored
Merge branch 'devel' into master
2 parents d5dcdbd + 6b6da02 commit df5edf7

File tree

10 files changed

+120
-25
lines changed

10 files changed

+120
-25
lines changed

.github/workflows/nix.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
os: [ubuntu, macos]
1212
steps:
1313
- uses: actions/checkout@v4
14-
- uses: cachix/install-nix-action@v27
14+
- uses: cachix/install-nix-action@V28
1515
- uses: cachix/cachix-action@v15
1616
with:
1717
name: gepetto

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- Default visualizer can be changed with `PINOCCHIO_VIEWER` environment variable ([#2419](https://github.com/stack-of-tasks/pinocchio/pull/2419))
12+
913
### Fixed
1014
- Fix linkage of Boost.Serialization on Windows ([#2400](https://github.com/stack-of-tasks/pinocchio/pull/2400))
1115
- Fix mjcf parser appending of inertias at root joint ([#2403](https://github.com/stack-of-tasks/pinocchio/pull/2403))
16+
- Fix unit tests with GCC 13.3 ([#2406](https://github.com/stack-of-tasks/pinocchio/pull/2416)
1217

1318
## [3.2.0] - 2024-08-27
1419

bindings/python/CMakeLists.txt

+8-2
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,14 @@ if(BUILD_PYTHON_INTERFACE)
224224

225225
# --- INSTALL VISUALIZATION SCRIPTS
226226
install_python_files(
227-
MODULE visualize FILES __init__.py base_visualizer.py gepetto_visualizer.py
228-
meshcat_visualizer.py panda3d_visualizer.py rviz_visualizer.py)
227+
MODULE visualize
228+
FILES __init__.py
229+
base_visualizer.py
230+
gepetto_visualizer.py
231+
meshcat_visualizer.py
232+
panda3d_visualizer.py
233+
rviz_visualizer.py
234+
visualizers.py)
229235

230236
# --- STUBS --- #
231237
if(GENERATE_PYTHON_STUBS)

bindings/python/pinocchio/robot_wrapper.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -413,14 +413,14 @@ def initViewer(self, share_data=True, *args, **kwargs):
413413
"""Init the viewer"""
414414
# Set viewer to use to MeshCat.
415415
if self.viz is None:
416-
from .visualize import MeshcatVisualizer
416+
from .visualize import Visualizer
417417

418418
data, collision_data, visual_data = None, None, None
419419
if share_data:
420420
data = self.data
421421
collision_data = self.collision_data
422422
visual_data = self.visual_data
423-
self.viz = MeshcatVisualizer(
423+
self.viz = Visualizer.default()(
424424
self.model,
425425
self.collision_model,
426426
self.visual_model,

bindings/python/pinocchio/visualize/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
from .meshcat_visualizer import MeshcatVisualizer
55
from .panda3d_visualizer import Panda3dVisualizer
66
from .rviz_visualizer import RVizVisualizer
7+
from .visualizers import Visualizer
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from enum import Enum
2+
from importlib.util import find_spec
3+
from os import environ
4+
5+
from .base_visualizer import BaseVisualizer
6+
from .gepetto_visualizer import GepettoVisualizer
7+
from .meshcat_visualizer import MeshcatVisualizer
8+
from .panda3d_visualizer import Panda3dVisualizer
9+
from .rviz_visualizer import RVizVisualizer
10+
11+
12+
class Visualizer(Enum):
13+
BASE = BaseVisualizer
14+
GEPETTO = GepettoVisualizer
15+
MESHCAT = MeshcatVisualizer
16+
PANDA3D = Panda3dVisualizer
17+
RVIZ = RVizVisualizer
18+
19+
@classmethod
20+
def default(cls):
21+
"""
22+
Allow user to choose their prefered viewer with eg.
23+
export PINOCCHIO_VIEWER=RVIZ.
24+
25+
Otherwise, try to find one which is installed.
26+
"""
27+
# Allow user to define which viewer they want
28+
if "PINOCCHIO_VIEWER" in environ:
29+
selected = environ["PINOCCHIO_VIEWER"].upper()
30+
if hasattr(cls, selected):
31+
return getattr(cls, selected).value
32+
err = (
33+
f"The visualizer '{selected}' is not available.\n"
34+
"Please set PINOCCHIO_VIEWER to something installed among:\n"
35+
"- meshcat\n"
36+
"- gepetto-viewer\n"
37+
"- panda3d\n"
38+
"- rviz\n"
39+
)
40+
raise ImportError(err)
41+
42+
# Otherwise, use the first available
43+
for v in ["meshcat", "gepetto", "panda3d_viewer", "rviz"]:
44+
if find_spec(v) is not None:
45+
return getattr(cls, v.replace("_viewer", "").upper()).value
46+
47+
err = (
48+
"No visualizer could be found.\n"
49+
"Please install one of those:\n"
50+
"- meshcat\n"
51+
"- gepetto-viewer\n"
52+
"- panda3d\n"
53+
"- rviz\n"
54+
)
55+
raise ImportError(err)

doc/d-practical-exercises/3-invkine.md

+23-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,29 @@ the null space of task 1 is:
152152

153153
\f$P_1 = I_9 - J_1^+ J_1\f$
154154

155-
\f$vq_2 = vq_1 + P_1 (J_2 P_1)^+ ( v_2^* - J_2 vq_1)\f$
155+
\f$vq_2 = vq_1 + P_1 (J_2 P_1)^+ (v_2^* - J_2 vq_1)\f$
156+
157+
With the mathematical property
158+
159+
\f$(J_2 P_1)^+ = P_1 (J_2 P_1)^+\f$
160+
161+
we can save a matrix multiplication:
162+
163+
\f$vq_2 = vq_1 + (J_2 P_1)^+ (v_2^* - J_2 vq_1)\f$
164+
165+
It is important to note that the null space of `J1` is defined up to a numeric
166+
threshold on its eigen values. A low threshold will lead to a trivial null space
167+
of `J1`, and task 2 could numerically interfere with task 1. It translates into
168+
setting an appropriate `rcond` or `rtol` when computing the pseudo-inverse of
169+
`J2 P1`:
170+
171+
```py
172+
pinv_J2_P1 = pinv(J2 @ P1, rcond=1e-3)
173+
```
174+
175+
Tuning `rcond` is a tradeoff: if `rcond` is too low (its default is `1e-15`),
176+
task 2 could interfere with task 1. If it is too high, there won't be enough
177+
DoFs to complete task 2.
156178

157179
#### Question 2
158180

flake.lock

+13-12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

+6-4
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33

44
inputs = {
55
flake-parts.url = "github:hercules-ci/flake-parts";
6-
#nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
7-
# use gepetto fork until https://github.com/NixOS/nixpkgs/pull/337942
8-
nixpkgs.url = "github:gepetto/nixpkgs";
6+
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
97
};
108

119
outputs =
@@ -22,7 +20,11 @@
2220
devShells.default = pkgs.mkShell { inputsFrom = [ self'.packages.default ]; };
2321
packages = {
2422
default = self'.packages.pinocchio;
25-
pinocchio = pkgs.python3Packages.pinocchio.overrideAttrs (_: {
23+
pinocchio = pkgs.python3Packages.pinocchio.overrideAttrs (super: {
24+
# avoid SIGTRAP on macos github runners
25+
cmakeFlags = super.cmakeFlags ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [
26+
"-DCMAKE_CTEST_ARGUMENTS=--exclude-regex;pinocchio-example-py-casadi-quadrotor-ocp"
27+
];
2628
src = pkgs.lib.fileset.toSource {
2729
root = ./.;
2830
fileset = pkgs.lib.fileset.unions [

include/pinocchio/algorithm/contact-info.hpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -742,9 +742,10 @@ namespace pinocchio
742742
if (current1_id > current2_id)
743743
{
744744
const JointModel & joint1 = model.joints[current1_id];
745+
const int j1nv = joint1.nv();
745746
joint1_span_indexes.push_back((Eigen::DenseIndex)current1_id);
746747
Eigen::DenseIndex current1_col_id = joint1.idx_v();
747-
for (int k = 0; k < joint1.nv(); ++k, ++current1_col_id)
748+
for (int k = 0; k < j1nv; ++k, ++current1_col_id)
748749
{
749750
colwise_joint1_sparsity[current1_col_id] = true;
750751
}
@@ -753,9 +754,10 @@ namespace pinocchio
753754
else
754755
{
755756
const JointModel & joint2 = model.joints[current2_id];
757+
const int j2nv = joint2.nv();
756758
joint2_span_indexes.push_back((Eigen::DenseIndex)current2_id);
757759
Eigen::DenseIndex current2_col_id = joint2.idx_v();
758-
for (int k = 0; k < joint2.nv(); ++k, ++current2_col_id)
760+
for (int k = 0; k < j2nv; ++k, ++current2_col_id)
759761
{
760762
colwise_joint2_sparsity[current2_col_id] = true;
761763
}
@@ -770,10 +772,11 @@ namespace pinocchio
770772
while (current_id > 0)
771773
{
772774
const JointModel & joint = model.joints[current_id];
775+
const int jnv = joint.nv();
773776
joint1_span_indexes.push_back((Eigen::DenseIndex)current_id);
774777
joint2_span_indexes.push_back((Eigen::DenseIndex)current_id);
775778
Eigen::DenseIndex current_row_id = joint.idx_v();
776-
for (int k = 0; k < joint.nv(); ++k, ++current_row_id)
779+
for (int k = 0; k < jnv; ++k, ++current_row_id)
777780
{
778781
colwise_joint1_sparsity[current_row_id] = true;
779782
colwise_joint2_sparsity[current_row_id] = true;

0 commit comments

Comments
 (0)