Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
168 commits
Select commit Hold shift + click to select a range
a10ce5a
Joints - Add a first implementation of joint spline
MegMll Oct 8, 2025
2a6edbe
Unittest - Add TU for spline joint
MegMll Oct 8, 2025
222c07a
Bindings - add bindings for spline joint
MegMll Oct 8, 2025
b4fd816
Spatial - Weird fix to make spline joint work for now (to remove)
MegMll Oct 8, 2025
fd21eba
Unittest - update joint unittests to include spline joints
MegMll Oct 10, 2025
18b3b92
SplineJoint - apply pre-commit
MegMll Oct 10, 2025
74c1e65
Spline - use the true cumulative form of the spline
MegMll Oct 10, 2025
fb53cdd
Spline - Add isEqual Method
MegMll Oct 13, 2025
c3c65b4
Spline - Add TU with finite difference
MegMll Oct 13, 2025
53d341a
Unittest - fix tests for spline joint
MegMll Oct 13, 2025
e88b923
Spline joint - change if/else to be casadi compatible
MegMll Oct 14, 2025
e12aa61
Joint Spline - Remove useless comments
MegMll Oct 15, 2025
588131a
Joint Spline - Fix indexing
MegMll Oct 15, 2025
6580fac
Joint Spline - Eigen No Malloc checked and passed
MegMll Oct 15, 2025
1f43b93
Spline joints - fix casadi joints tests
MegMll Oct 15, 2025
09e89fa
Joint Spline - Add a build method
MegMll Oct 16, 2025
2e51cc5
Unittest - Fix joint spline's unittests
MegMll Oct 16, 2025
534c69d
Model-graph - Add spline joint to model graph
MegMll Oct 16, 2025
c72f2c5
JointSpline - make some correction to the joint
MegMll Oct 20, 2025
d5d163c
TU - apply new jointSpline constructor
MegMll Oct 20, 2025
4d49886
ModelGraph - use new JointSpline method
MegMll Oct 20, 2025
72d162b
Serialization - Add attributes from spline model and data
MegMll Oct 21, 2025
9b6d290
Unittest - use std vector instead of se3
MegMll Oct 21, 2025
34b0d4e
JointSpline - Diverse Changes
MegMll Oct 21, 2025
fff96bb
Casadi - Add a separated file for findSpan to be able to do specializ…
MegMll Oct 21, 2025
0a07743
Bindings - modify joint spline binding
MegMll Oct 21, 2025
470ba33
JointSpline - Remove findSpan
MegMll Oct 21, 2025
3cf9774
Unittest - remove buildJoint function
MegMll Oct 21, 2025
2a4074b
ModelGraph - finish adding jointSpline to model graph + unittest
MegMll Oct 21, 2025
f092510
cppadcg: Fix cppadcg cast test with spline joint
jorisv Oct 22, 2025
6a961ee
multiprecision: Fix multiprecision cast test with Spline joint
jorisv Oct 22, 2025
3bdd00c
multiprecision: Add missing header
jorisv Oct 22, 2025
8250c0a
lint: Run linter
jorisv Oct 22, 2025
55d3eaa
JointSpline - Removed comments
MegMll Oct 22, 2025
315dfe1
JointSpline - move bspline functions in public to be able to test it
MegMll Oct 22, 2025
28c2fba
Unittest - add more test for joint spline
MegMll Oct 22, 2025
19742de
Bindings - Add another constructor for joint spline
MegMll Oct 23, 2025
e9e2a4a
Unittest - put full knee trajectory
MegMll Oct 23, 2025
db1fbf4
Unittest - fix getTrajectory function
MegMll Oct 23, 2025
df7bb40
Bindings - add modelgraph bindings constant
MegMll Oct 27, 2025
c911491
JointSpline - Fix indexing
MegMll Oct 27, 2025
c709e01
JointSpline - Add a doc
MegMll Oct 27, 2025
0987757
JointSpline - Fix bias computation
MegMll Oct 27, 2025
dbc51a9
Unittest - add a finite difference test for S and bias c for JointSpline
MegMll Oct 27, 2025
71b4101
JointSpline - Add comments and complete isEqual function
MegMll Oct 28, 2025
29c6fc4
Unittest - Try to add tolerance to see if it fixes macos-intel problem
MegMll Oct 28, 2025
2f6f0fb
Unittest - fix compilation error
MegMll Oct 28, 2025
109ce2f
JointSpline - add assert for configuration to be between 0 and 1
MegMll Oct 30, 2025
0d42a74
Bindings - Add graph spline joints bindings
MegMll Oct 30, 2025
8224e91
Algo/Splines - remove comments
MegMll Oct 30, 2025
3a9a244
Unittest - add find span test for q = 0
MegMll Oct 30, 2025
77dfab7
Changelog - update
MegMll Oct 30, 2025
3eea325
JointSpline - remove SE3 and use Transformation_t
MegMll Oct 30, 2025
5f5c210
Unittest - remove comments
MegMll Oct 30, 2025
365d826
JointSpline - Use transformation_t and motion_t
MegMll Oct 30, 2025
adaa24d
Examples - Add a small examples on what the spline joint can do
MegMll Oct 30, 2025
5c003e8
Unittest - Specialize for joint spline
MegMll Oct 30, 2025
87591d1
Examples - add spline joint examples
MegMll Oct 30, 2025
9e5649e
Unittest - Fix joint generic test for joint spline
MegMll Nov 3, 2025
db514f5
Examples - Fix some linting errors
MegMll Nov 3, 2025
8becc17
JointSpline - Disable assert
MegMll Nov 4, 2025
c526591
core: Apply small changes
jorisv Nov 25, 2025
174470a
Algo/splines - add doc
MegMll Nov 26, 2025
1933556
Unittest - Avoid code duplication for randomConfig vector generation
MegMll Nov 26, 2025
8244f2d
Unittest - more complex and complete tests
MegMll Nov 26, 2025
dce59cb
Unittest/cppad - use degree 3 spline joint
MegMll Nov 27, 2025
96f6fab
unittest - change name of struct to be more generic
MegMll Nov 27, 2025
7db87e4
unittest - avoid code duplication
MegMll Nov 27, 2025
539813a
unittest - avoid code duplication
MegMll Nov 27, 2025
60a1bed
Unittest - fix casadi/joints test
MegMll Dec 9, 2025
e315f77
Unittest - add forgotten helical unaligned joint
MegMll Dec 10, 2025
8a3df20
Unittest - Fix casadi test for universal joints
MegMll Dec 11, 2025
4ae2d28
Mode-graph - use new function for joint spline
MegMll Dec 11, 2025
1057886
Linting
MegMll Dec 12, 2025
9575d2e
unittest - fix new joint
MegMll Dec 12, 2025
022126e
JointSpline - Fix bias computation
MegMll Dec 12, 2025
3dc2652
Unittest - Fix finite-difference test
MegMll Dec 12, 2025
d5f3c01
unittest - use config vector of joints
MegMll Dec 12, 2025
1fae00c
unittest - remove useless lines
MegMll Dec 12, 2025
6c1e84d
Unittest - Add a utils file to centralize init of joints with parameters
MegMll Dec 15, 2025
0294c22
Run pre-commit
MegMll Dec 15, 2025
eb41d3c
unittest/utils - Fix mimic init
MegMll Dec 15, 2025
fcc53be
Core - update spline to allow spans to be between min and max, instea…
MegMll Apr 14, 2026
f9b983d
core - move joint spline definition
MegMll Apr 14, 2026
8fcc9a1
core - update splines algorithms
MegMll Apr 14, 2026
20baa07
core - add spline joint
MegMll Apr 14, 2026
4b7ec2f
parser - add spline joint
MegMll Apr 14, 2026
bd6fa64
core - fix some errors and warnings (some errors due to rebase still …
MegMll Apr 14, 2026
34ab05f
unittest - use jointModelWithParameters
MegMll Apr 15, 2026
5a70e46
unittest - use std::vector
MegMll Apr 15, 2026
efe4c1d
remove useless file
MegMll Apr 15, 2026
b05323e
unittest - fix compilation warnings
MegMll Apr 15, 2026
c81ec80
unittest - add spline joint to serialization test
MegMll Apr 15, 2026
ff32ecf
unittest - update serialization test to use jointModelWithParameters
MegMll Apr 17, 2026
88186fc
unittest - clean, remove comments
MegMll Apr 17, 2026
be6d1b8
fix cmake: @lucasJoseph
Ipuch Apr 23, 2026
cce666a
fix: splines.hpp to sources.cmake
Ipuch May 5, 2026
9dc293f
core : factorize code calc functions
MegMll May 6, 2026
954e47f
core : finish adding min/max for the knot vector + fix knot vector co…
MegMll May 6, 2026
0b66bd2
unittest : modify knot unittest to test min/max
MegMll May 6, 2026
1f6901d
core : add min/max for spline joint
MegMll May 6, 2026
6352ef7
refactor: decoupling the knotvector scaling
Ipuch May 6, 2026
7da5f68
tests: joint-generic bounding q with joint limits
Ipuch May 7, 2026
b9c2643
spline: Apply new header convention
jorisv Jun 2, 2026
10e86da
spline: Fix build
jorisv Jun 3, 2026
dbc38fb
core - add a new struct JointSplineBuilder
MegMll Jun 3, 2026
fd961e4
unittest - update tests to use new builder struct
MegMll Jun 3, 2026
e53faca
model-graph - update jointSpline
MegMll Jun 3, 2026
84ee9a0
bindings - update jointSpline bindings
MegMll Jun 3, 2026
2352f3e
graph: Explain why we can't reverse the joint
jorisv Jun 5, 2026
52903fc
core - move splines algos into internal and/or private
MegMll Jun 5, 2026
3d377e1
core - make test casadi compatible
MegMll Jun 8, 2026
4cc4b5b
unittest - Fix degree
MegMll Jun 8, 2026
719fe67
unittest - Make tset compatible with new internal api
MegMll Jun 8, 2026
5f204b8
unittest: Fix joint-init.hpp build
jorisv Jun 5, 2026
2e3a900
unittest: Use joint-init.hpp in visitor.cpp
jorisv Jun 5, 2026
6abe11f
unittest: Use joint-init.hpp in joint-motion-subspace.cpp
jorisv Jun 5, 2026
0396b77
unittest: Use joint-init.hpp in all-joints.cpp
jorisv Jun 5, 2026
3f17fbf
unittest: Remove dead code
jorisv Jun 5, 2026
2bb46e9
mpfr: Remove useless include
jorisv Jun 5, 2026
10c41e3
changelog: Set in Unreleased and add example link
jorisv Jun 5, 2026
55c905a
casadi: Fix scalar casting
jorisv Jun 5, 2026
7c0b85d
casadi: Fix expression evaluation
jorisv Jun 5, 2026
e9d59b1
graph: Add JointSplineBuilder
jorisv Jun 8, 2026
a0f3a96
joint: Remove moved methods
jorisv Jun 8, 2026
1b68377
joint: Remove one warning
jorisv Jun 8, 2026
83b2af7
casadi: Fix build
jorisv Jun 8, 2026
6c5def0
python: Fix binding build and add graph::JointSplineBuilder
jorisv Jun 8, 2026
5fce325
examples: Use coal and run when running ctest
jorisv Jun 8, 2026
1f72d6c
python: Add JointModelSplineBuilder binding
jorisv Jun 8, 2026
03d98fd
lint: Apply clang-format
jorisv Jun 8, 2026
51e9302
joint: Remove warning
jorisv Jun 8, 2026
b061b3e
unittest: Use builder to build joint
jorisv Jun 8, 2026
e4294e1
unittest: Fix cppad-joints build
jorisv Jun 8, 2026
a55eb74
unittest - rewrite most tests to use internal functions directly
MegMll Jun 9, 2026
8a794f1
core - write correct test for range inside basis function computation
MegMll Jun 9, 2026
26da239
example: knee with spline joint.
Ipuch Jun 10, 2026
55f4611
example: spline knee joint with better curves.
Ipuch Jun 10, 2026
5211976
example: spline knee joint make it minimal
Ipuch Jun 11, 2026
bb6850e
example: parabola in spline-joint.py
Ipuch Jun 11, 2026
c77dec8
spline: Fix FindSpan and improve tests
jorisv Jun 11, 2026
fc163ef
test: Relax precision on finite-differences test
jorisv Jun 11, 2026
5ceeac4
test: fix some assert and remove warnings
jorisv Jun 11, 2026
ea3a114
spline: Remove more warnings
jorisv Jun 11, 2026
5011384
unittest: Use an open uniform spline by default to help numerical pre…
jorisv Jun 12, 2026
fbd0bf6
unittest: Add a bound test to bsplineBasis
jorisv Jun 12, 2026
696acb7
python: Expose JointDataSpline specialized members
jorisv Jun 12, 2026
4398c72
warning: Remove a bunch of clang warning
jorisv Jun 12, 2026
dbd7b9d
core - add Continuity check over knot vector
MegMll Jun 17, 2026
e83306a
unittest - add test for basis function continuity
MegMll Jun 17, 2026
220ac50
unittest - fix unittest for basis function derivatives (finite differ…
MegMll Jun 17, 2026
5f8ef41
examples - apply linting
MegMll Jun 17, 2026
c901379
spline: Add deBoor algorithm to evaluate the BSpline
jorisv Jul 9, 2026
9643d8e
spline: Remove warnings
jorisv Jul 9, 2026
5f738ea
spline: Implement deBoorCumBasisSparse
jorisv Jul 9, 2026
7375020
spline: Rename deBoorBasis into deBoor
jorisv Jul 9, 2026
64e9aa9
spline: Add bsplineBasis to compute all basis function with minimal c…
jorisv Jul 15, 2026
ec7039b
spline: Remove other deBoor like algorithm
jorisv Jul 15, 2026
6ad5593
spline: Add comments
jorisv Jul 15, 2026
c50af03
spline: First working version with deBoorBasis
jorisv Jul 15, 2026
f90968f
spline: Add standalone function to compute cumulative bspline derivat…
jorisv Jul 16, 2026
c84a983
spline: Move bsplineBasis in unit tests and test cumulativeBasisDeriv…
jorisv Jul 16, 2026
dd672f7
spline: Fix build
jorisv Jul 16, 2026
c67c201
spline: Add deBoorFullBasis function
jorisv Jul 17, 2026
cbd4841
spline: Improve doc and comments
jorisv Jul 17, 2026
55604f2
spline: Add Full variant to support casadi
jorisv Jul 17, 2026
0c2cc04
spline: Refactor code to implement spline transformation on minimal a…
jorisv Jul 17, 2026
66ff657
spline: Add computeSplineKinematicsFull
jorisv Jul 17, 2026
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Extended `ModelTpl::addJoint` overload to accept `min_acceleration`, `max_acceleration`, `min_jerk`, `max_jerk` parameters
- Add `PINOCCHIO_BUILD_BINDING_WITH_PCH` CMake option to use PCH to build Python bindings (default OFF) ([#2886](https://github.com/stack-of-tasks/pinocchio/pull/2886))
- Add PINOCCHIO_BUILD_VISUALIZERS option ([#2900](https://github.com/stack-of-tasks/pinocchio/pull/2900))
- Add spline joint (JointModelSplineTpl) to default joint collection ([#2784](https://github.com/stack-of-tasks/pinocchio/pull/2784))
- [Python example here](./examples/spline-joint.py)

### Fixed

Expand Down
46 changes: 46 additions & 0 deletions bindings/python/parsers/graph/expose-edges.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ namespace pinocchio

const int JointMimic::nq;
const int JointMimic::nv;

const int JointSpline::nq;
const int JointSpline::nv;
} // namespace graph

namespace python
Expand Down Expand Up @@ -160,6 +163,49 @@ namespace pinocchio
.def_readonly("nq", &JointUniversal::nq, "Number of configuration variables.")
.def_readonly("nv", &JointUniversal::nv, "Number of tangent variables.");

bp::class_<JointSpline>(
"JointSpline", "Represents a spline-based joint.",
bp::init<>(bp::args("self"), "Default constructor."))
.def(
bp::init<const std::vector<SE3> &, const Eigen::VectorXd &, std::size_t>(
bp::args("self", "ctrlFrame", "knots", "degree"),
"Constructor with a single control frame and degree."))
.def_readwrite("ctrlFrames", &JointSpline::ctrlFrames, "Control frames of the spline.")
.def_readwrite("knots", &JointSpline::knots, "Control frames of the spline.")
.def_readwrite("degree", &JointSpline::degree, "Degree of the spline.")
.def_readonly("nq", &JointSpline::nq, "Number of configuration variables.")
.def_readonly("nv", &JointSpline::nv, "Number of tangent variables.");

bp::class_<JointSplineBuilder>(
"JointSplineBuilder", "JointSpline builder helper.",
bp::init<>(bp::args("self"), "Default constructor."))
.def(
"addControlFrame", &JointSplineBuilder::addControlFrame, bp::return_self<>(),
(bp::arg("self"), bp::arg("frame")), "Add a B-spline control frame")
.def(
"withControlFrameVector", &JointSplineBuilder::withControlFrameVector,
bp::return_self<>(), (bp::arg("self"), bp::arg("frames")),
"Set B-spline control frame vector")
.def(
"withDegree", &JointSplineBuilder::withDegree, bp::return_self<>(),
(bp::arg("self"), bp::arg("degree")), "Set B-spline degree")
.def(
"withKnotVector",
+[](JointSplineBuilder & builder, const std::vector<double> & k) -> auto {
return builder.withKnotVector(k);
},
bp::return_self<>(), (bp::arg("self"), bp::arg("knots")), "Set B-spline knot vector")
.def(
"withOpenUniformKnots", &JointSplineBuilder::withOpenUniformKnots, bp::return_self<>(),
(bp::arg("self"), bp::arg("min"), bp::arg("max")),
"Set B-spline knot vector as open uniform")
.def(
"withUniformKnots", &JointSplineBuilder::withUniformKnots, bp::return_self<>(),
(bp::arg("self"), bp::arg("min"), bp::arg("max")), "Set B-spline knot vector as uniform")
.def(
"build", &JointSplineBuilder::build, (bp::arg("self")),
"Build a JointSpline from provided parameters");

bp::class_<JointComposite>(
"JointComposite", "Represents a composite joint.",
bp::init<>(bp::args("self"), "Default constructor."))
Expand Down
2 changes: 2 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ if(BUILD_PYTHON_INTERFACE)
simulation-closed-kinematic-chains
simulation-lcaba
model-graph-geometry
spline-joint
spline-joint-knee
)
if(BUILD_WITH_URDF_SUPPORT)
list(
Expand Down
146 changes: 146 additions & 0 deletions examples/spline-joint-knee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
"""Knee spline joint driven by its physical flexion angle.

This example uses the SE(3) spline joint (``pin.JointModelSpline`` /
``pin.JointModelSplineBuilder``) to reproduce experimental knee kinematics: the
joint constrains its child (tibia) frame to a cumulative B-spline on SE(3)
defined by a list of control frames, a knot vector and a degree

source: Lee, S. H., & Terzopoulos, D. (2008).
Spline joints for multibody dynamics. In ACM SIGGRAPH 2008 papers (pp. 1-8).

The 8 control frames below were fit offline (Gauss-Newton, degree=3, n_ctrl=8)
to a planar OpenSim knee, where the tx/ty translations the rotation
about Z (knee flexion) are driven by knee flexion itself.
"""

import time
from pathlib import Path

import coal
import meshcat.geometry as mg
import numpy as np
import pinocchio as pin
from pinocchio.visualize import MeshcatVisualizer

# Bones: mesh folder, OpenSim (subject-specific) scale factors and display color.
MESH_DIR = Path(__file__).resolve().parent.parent / "models" / "biomechanics"
FEMUR_SCALE, TIBIA_SCALE = 1.17378, 1.12373
BONE_COLOR = np.array([0.96, 0.94, 0.86, 0.7]) # bone ivory, semi-transparent.

# Recenter so the femoral condyle (knee) sits at the world origin instead of the
# hip: the fixed femur and the spline joint are both lifted by the knee offset.
KNEE_FROM_HIP = np.array([-0.0046, -0.4644, 0.0])
RECENTER = pin.SE3(np.eye(3), -KNEE_FROM_HIP)

# Control frames from the offline 2D-knee regression, as (yaw [rad], tx, ty [m]).
CONTROL_FRAMES = [
(-2.094400, -0.003842, -0.496205),
(-1.815147, 0.001278, -0.489246),
(-1.256640, 0.006243, -0.480186),
(-0.418880, -0.002220, -0.466444),
(0.418880, -0.008427, -0.463391),
(1.256640, -0.005740, -0.461613),
(1.815147, -0.006127, -0.464906),
(2.094400, -0.006285, -0.464416),
]


def mesh_object(name, parent_joint, stl, scale, placement):
"""Build a mesh GeometryObject fixed to ``parent_joint`` at ``placement``."""
mesh_scale = scale * np.ones(3)
geom = coal.MeshLoader().load(str(stl), mesh_scale)
obj = pin.GeometryObject(name, parent_joint, placement, geom, str(stl), mesh_scale)
obj.meshColor = BONE_COLOR
return obj


class PointTracer:
"""Trace a fixed point in Meshcat, keeping the dotted trail."""

def __init__(self, viz, name, point=None, color=0xFF3030, size=0.004):
self._world_to_femur = RECENTER.inverse()
self._point = np.zeros(3) if point is None else np.asarray(point, float)
self._material = mg.PointsMaterial(size=size, color=color)
self._trail = []
self._node = viz.viewer[f"tibia_traces/{name}"]
self._node.set_transform(RECENTER.homogeneous)

def add(self, tibia_pose):
self._trail.append(self._world_to_femur.act(tibia_pose.act(self._point)))
pts = np.asarray(self._trail, dtype=np.float32).T
self._node.set_object(mg.Points(mg.PointsGeometry(pts), self._material))


def main():

control_frames = [
pin.SE3(pin.rpy.rpyToMatrix(0.0, 0.0, yaw), np.array([tx, ty, 0.0]))
for (yaw, tx, ty) in CONTROL_FRAMES
]

# Knee-angle domain of the fitted spline (in degree).
THETA_MIN_DEG, THETA_MAX_DEG = -120.0, 120.0

knee = (
pin.JointModelSplineBuilder()
.withDegree(
3
) # degree of the splines, degree 3 means acceleration is continuous.
.withControlFrameVector(control_frames) # list of SE3 transforms
.withOpenUniformKnots(
THETA_MIN_DEG, THETA_MAX_DEG
) # Map knee flexion angle (degrees) to spline parameter q in [0, 1].
.build()
)
model = pin.Model()
joint_id = model.addJoint(0, knee, RECENTER, "knee")

# visual only code
try:
visual_model = pin.GeometryModel()
visual_model.addGeometryObject(
mesh_object("femur", 0, MESH_DIR / "femur_r.stl", FEMUR_SCALE, RECENTER)
)
visual_model.addGeometryObject(
mesh_object(
"tibia",
joint_id,
MESH_DIR / "tibia_r.stl",
TIBIA_SCALE,
pin.SE3.Identity(),
)
)

viz = MeshcatVisualizer(model, None, visual_model)
viz.initViewer(open=True)
viz.loadViewerModel()

except ImportError as e:
print("Error while initializing the viewer.")
print(e)
return

# Trace tibia-frame points and show the tibia frame as a triad, updated every step.
plateau = np.array([0.03100708, -0.03819558, -0.00347008])
tracers = [
PointTracer(viz, "origin", color=0xFF3030),
PointTracer(viz, "plateau", plateau, color=0x3060FF),
]
tibia_frame = viz.viewer["tibia_frame"]
tibia_frame.set_object(mg.triad(0.08))

# Sweep the physical knee angle (+10 deg hyperextension to -120 deg flexion),
angles = np.linspace(10.0, -120.0, 120)
angles = np.concatenate([angles, angles[::-1]])
for _ in range(5):
for theta_deg in angles:
viz.display(np.array([theta_deg]))
tibia_pose = viz.data.oMi[joint_id]
for tracer in tracers:
tracer.add(tibia_pose)
tibia_frame.set_transform(tibia_pose.homogeneous)
time.sleep(0.015)


if __name__ == "__main__":
main()
111 changes: 111 additions & 0 deletions examples/spline-joint.py
Comment thread
jorisv marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import time

import meshcat.geometry as mg
import numpy as np
import pinocchio as pin
from pinocchio.visualize import MeshcatVisualizer


class PointTracer:
"""Trace a fixed point in Meshcat, keeping the dotted trail."""

def __init__(self, viz):
self._material = mg.PointsMaterial(size=0.004, color=0xFF3030)
self._trail = []
self._node = viz.viewer["solid_pose"]

def add(self, solid_pose):
self._trail.append(solid_pose.translation.copy())
pts = np.asarray(self._trail, dtype=np.float32).T

line = mg.Line(
geometry=mg.PointsGeometry(pts),
material=mg.LineBasicMaterial(color=0xFF3030),
)
self._node.set_object(geometry=line)


def main():

PARABOLA_CONTROL_FRAMES = [
(-1.000000, 1.000000),
(-0.888889, 0.777778),
(-0.666667, 0.407407),
(-0.333333, 0.074074),
(0.000000, -0.037037),
(0.333333, 0.074074),
(0.666667, 0.407407),
(0.888889, 0.777778),
(1.000000, 1.000000),
]

control_frames = [
pin.SE3(np.eye(3), np.array([0, ty, tz]))
for (ty, tz) in PARABOLA_CONTROL_FRAMES
]

# Create a Pinocchio model with a single free-flyer joint
model = pin.Model()
spline_joint = (
pin.JointModelSplineBuilder()
.withDegree(3)
.withControlFrameVector(control_frames)
.withOpenUniformKnots(-1, 1)
.build()
)
joint_id = model.addJoint(0, spline_joint, pin.SE3.Identity(), "spline-joint")

# adding some inertia to drop the solid in the parabola
box_size = 1.0 # edge length of each cube [m]
box_mass = 1.0 # mass of each cube [kg]
box_inertia = pin.Inertia.FromBox(box_mass, box_size, box_size, box_size)
model.appendBodyToJoint(joint_id, box_inertia, pin.SE3.Identity())

# visual only code
try:
visual_model = pin.GeometryModel()

viz = MeshcatVisualizer(model, None, visual_model)
viz.initViewer(open=True)
viz.loadViewerModel()

except ImportError as e:
print("Error while initializing the viewer.")
print(e)
return

tracers = [PointTracer(viz)]
solid_frame = viz.viewer["solid_frame"]
solid_frame.set_object(mg.triad(0.2))

dt = 0.01
qs, _ = sim_loop(model, dt)

for theta in qs:
viz.display(np.array([theta]))
solid_pose = viz.data.oMi[joint_id]
for tracer in tracers:
tracer.add(solid_pose)
solid_frame.set_transform(solid_pose.homogeneous)
time.sleep(dt)


def sim_loop(model, dt=0.01, nsteps=800):

qs = [np.array([1.0])]
vs = [np.array([0])]
data = model.createData()
for i in range(nsteps):
q = qs[i]
v = vs[i]
tau = -1 * v # a little bit of damping
a1 = pin.aba(model, data, q, v, tau)
vnext = v + dt * a1
qnext = pin.integrate(model, q, dt * vnext)
qs.append(qnext)
vs.append(vnext)
return qs, vs


if __name__ == "__main__":
main()
2 changes: 2 additions & 0 deletions include/pinocchio/autodiff/casadi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "pinocchio/eigen-common.hpp"
#include "pinocchio/math.hpp"
#include "pinocchio/spatial.hpp"
#include "pinocchio/src/multibody/joint/spline-utils.hxx"
// IWYU pragma: end_keep

namespace boost
Expand Down Expand Up @@ -349,4 +350,5 @@ namespace Eigen
#include "pinocchio/src/autodiff/casadi/math/triangular-matrix.hxx"
#include "pinocchio/src/autodiff/casadi/spatial/se3-tpl.hxx"
#include "pinocchio/src/autodiff/casadi/utils/static-if.hxx"
#include "pinocchio/src/autodiff/casadi/multibody/joint/spline-utils.hxx"
// IWYU pragma: end_exports
4 changes: 4 additions & 0 deletions include/pinocchio/bindings/python/context/generic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ namespace pinocchio
typedef JointModelUniversalTpl<Scalar> JointModelUniversal;
typedef JointDataUniversalTpl<Scalar> JointDataUniversal;

typedef JointModelSplineTpl<Scalar> JointModelSpline;
typedef JointModelSplineBuilderTpl<Scalar> JointModelSplineBuilder;
typedef JointDataSplineTpl<Scalar> JointDataSpline;

typedef JointModelTranslationTpl<Scalar> JointModelTranslation;
typedef JointDataTranslationTpl<Scalar> JointDataTranslation;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,11 @@ namespace pinocchio
.add_property("StU", &JointDataComposite::StU);
}

template<>
inline bp::class_<JointDataSpline> &
expose_joint_data<JointDataSpline>(bp::class_<JointDataSpline> & cl)
{
return cl.add_property("N", &JointDataSpline::N);
}
} // namespace python
} // namespace pinocchio
Loading
Loading