pinocchio 4.1.0
A fast and flexible implementation of Rigid Body Dynamics algorithms and their analytical derivatives
Loading...
Searching...
No Matches
constraint-model-base.hpp
1//
2// Copyright (c) 2025 INRIA
3//
4
5#pragma once
6
7#include <boost/python.hpp>
8#include <eigenpy/exception.hpp>
9#include <eigenpy/eigen-to-python.hpp>
10
11#include "pinocchio/multibody.hpp"
12#include "pinocchio/constraints.hpp"
13
14#include "pinocchio/bindings/python/fwd.hpp"
15#include "pinocchio/bindings/python/utils/macros.hpp"
16#include "pinocchio/bindings/python/utils/eigen.hpp"
17#include "pinocchio/bindings/python/algorithm/constraints/baumgarte-corrector-parameters.hpp"
18
19namespace pinocchio
20{
21 namespace python
22 {
23
24 namespace bp = boost::python;
25
26 template<class ConstraintModelDerived>
28 : public bp::def_visitor<ConstraintModelBasePythonVisitor<ConstraintModelDerived>>
29 {
30 typedef ConstraintModelDerived Self;
31 typedef typename ::pinocchio::traits<Self>::ConstraintModel ConstraintModel;
32 typedef typename ::pinocchio::traits<Self>::ConstraintData ConstraintData;
33 typedef typename ::pinocchio::traits<Self>::Scalar Scalar;
34
35 typedef typename ::pinocchio::traits<Self>::ConstraintSet ConstraintSet;
36 typedef typename ::pinocchio::traits<Self>::JordanOperation JordanOperation;
37
38 typedef typename ::pinocchio::traits<Self>::ResidualVectorType ResidualVectorType;
39 typedef typename ::pinocchio::traits<Self>::JacobianMatrixType JacobianMatrixType;
40 typedef typename ::pinocchio::traits<Self>::ConeVectorType ConeVectorType;
41 typedef typename ::pinocchio::traits<Self>::ConeScalingVectorType ConeScalingVectorType;
42
43 static constexpr bool has_baumgarte_corrector =
44 ::pinocchio::traits<Self>::has_baumgarte_corrector;
45 static constexpr bool has_set = ::pinocchio::traits<Self>::has_set;
46
47 typedef context::Model Model;
48 typedef context::Data Data;
49 typedef std::vector<context::Force> ForceVector;
50 typedef std::vector<context::Motion> MotionVector;
51
52 typedef typename Self::BooleanVector BooleanVector;
53 typedef typename Self::EigenIndexVector EigenIndexVector;
54
55 typedef BaumgarteCorrectorParametersTpl<context::Scalar> BaumgarteCorrectorParameters;
56
57 public:
58 template<class PyClass>
59 void visit(PyClass & cl) const
60 {
61 cl.PINOCCHIO_ADD_PROPERTY(Self, name, "Name of the constraint.")
62#ifndef PINOCCHIO_PYTHON_SKIP_COMPARISON_OPERATIONS
63 .def(bp::self == bp::self)
64 .def(bp::self != bp::self)
65#endif
66 .def("classname", &Self::classname)
67 .staticmethod("classname")
68 .def("shortname", &Self::shortname, "Short name of the class.")
69 .def(
70 "createData", &Self::createData, "Create a Data object for the given constraint model.")
71 .def(
72 "residualSize", &residualSize,
73 (bp::arg("self"), bp::arg("sel") = ConstraintSelectionType::CURRENT),
74 "Constraint size for the selection.")
75 .def(
76 "symmetricConeResidualSize", &symmetricConeResidualSize,
77 (bp::arg("self"), bp::arg("sel") = ConstraintSelectionType::CURRENT),
78 "Symmetric cone residual size for the selection.")
79 .def(
80 "setCompliance", &setCompliance,
81 (bp::arg("self"), bp::arg("vec"), bp::arg("sel") = ConstraintSelectionType::CURRENT),
82 "Set the compliance value for the selected constraint.")
83 .def(
84 "retrieveCompliance", &retrieveCompliance,
85 (bp::arg("self"), bp::arg("sel") = ConstraintSelectionType::CURRENT),
86 "Retrieve the compliance value for the selected constraint.")
87 .def(
88 "setBaumgarteCorrectorParameters", &setBaumgarteCorrectorParameters,
89 (bp::arg("self"), bp::arg("bp"), bp::arg("sel") = ConstraintSelectionType::CURRENT),
90 "Set the Baumgarte parameters.");
91 if constexpr (has_baumgarte_corrector)
92 {
93 cl.add_property(
94 "baumgarte_corrector_parameters",
95 bp::make_function( //
96 +[](const Self & self) -> const BaumgarteCorrectorParameters & {
97 return self.baumgarte_corrector_parameters();
98 },
99 bp::return_internal_reference<>()),
100 bp::make_function( //
101 +[](Self & self, const BaumgarteCorrectorParameters & copy) {
102 self.baumgarte_corrector_parameters() = copy;
103 },
104 bp::return_internal_reference<>()),
105 "Baumgarte parameters associated with the constraint.");
106 }
107 if constexpr (has_set)
108 {
109 cl.def(
110 "set",
111 +[](const Self & self, const ConstraintData & cdata) -> ConstraintSet {
112 return self.set(cdata);
113 },
114 bp::args("self", "constraint_data"), "Constraint set.");
115 }
116 cl.def(
117 "calc", &calc, bp::args("self", "model", "data", "constraint_data"),
118 "Evaluate the constraint values at the current state given by data and store the "
119 "results.")
120 .def(
121 "getRowSparsityPattern",
122 bp::make_function(
123 +[](
124 const Self & self, const Model & model, const Data & data,
125 const ConstraintData & cdata, const Eigen::Index row_id) -> BooleanVector {
126 BooleanVector res;
127 self.getRowSparsityPattern(model, data, cdata, row_id, res);
128 return res;
129 }),
130 "Active colwise sparsity associated with a given row.")
131 .def(
132 "getRowIndexes",
133 bp::make_function(
134 +[](
135 const Self & self, const Model & model, const Data & data,
136 const ConstraintData & cdata, const Eigen::Index row_id) -> EigenIndexVector {
137 EigenIndexVector res;
138 self.getRowIndexes(model, data, cdata, row_id, res);
139 return res;
140 }),
141 "Vector of the active indexes associated with a given row.")
142 .def(
143 "jacobian",
144 (JacobianMatrixType (Self::*)(const Model &, const Data &, ConstraintData &) const)
145 & Self::jacobian,
146 bp::args("self", "model", "data", "constraint_data"),
147 "Compute the constraint jacobian.")
148 .def(
149 "jacobianMatrixProduct", &jacobianMatrixProduct,
150 bp::args("self", "model", "data", "constraint_data", "matrix"),
151 "Forward chain rule: return product between the jacobian and a matrix.")
152 .def(
153 "jacobianTransposeMatrixProduct", &jacobianTransposeMatrixProduct,
154 bp::args("self", "model", "data", "constraint_data", "matrix"),
155 "Backward chain rule: return product between the jacobian transpose and a matrix.")
156 .def(
157 "mapConstraintForceToJointSpace", &mapConstraintForceToJointSpace,
158 (bp::arg("self"), bp::arg("model"), bp::arg("data"), bp::arg("constraint_data"),
159 bp::arg("constraint_forces"), bp::arg("joint_forces"),
160 bp::arg("reference_frame") = LOCAL),
161 "Map constraint forces to joint space.")
162 .def(
163 "mapJointSpaceToConstraintMotion", &mapJointSpaceToConstraintMotion,
164 (bp::arg("self"), bp::arg("model"), bp::arg("data"), bp::arg("constraint_data"),
165 bp::arg("joint_motions"), bp::arg("joint_generalized_velocity"),
166 bp::arg("reference_frame") = LOCAL),
167 "Map joint space quantities to constraint motion.")
168 .def(
169 "appendCouplingConstraintInertias", &appendCouplingConstraintInertias,
170 (bp::arg("self"), bp::arg("model"), bp::arg("data"), bp::arg("constraint_data"),
171 bp::arg("diagonal_constraint_inertia"), bp::arg("reference_frame") = LOCAL),
172 "Append to data the apparent inertia due to the constraint.");
173 }
174
175 static int residualSize(const Self & self, ConstraintSelectionType sel)
176 {
177 switch (sel)
178 {
179 case ConstraintSelectionType::CURRENT:
180 return self.residualSize(CurrentSelection());
181 case ConstraintSelectionType::MAXIMAL:
182 return self.residualSize(MaximalSelection());
183 default:
184 PINOCCHIO_UNREACHABLE();
185 }
186 }
187
188 static int symmetricConeResidualSize(const Self & self, ConstraintSelectionType sel)
189 {
190 switch (sel)
191 {
192 case ConstraintSelectionType::CURRENT:
193 return self.symmetricConeResidualSize(CurrentSelection());
194 case ConstraintSelectionType::MAXIMAL:
195 return self.symmetricConeResidualSize(MaximalSelection());
196 default:
197 PINOCCHIO_UNREACHABLE();
198 }
199 }
200
201 static int symmetricConeResidualScalingSize(const Self & self, ConstraintSelectionType sel)
202 {
203 switch (sel)
204 {
205 case ConstraintSelectionType::CURRENT:
206 return self.symmetricConeResidualScalingSize(CurrentSelection());
207 case ConstraintSelectionType::MAXIMAL:
208 return self.symmetricConeResidualScalingSize(MaximalSelection());
209 default:
210 PINOCCHIO_UNREACHABLE();
211 }
212 }
213
214 static void
215 setCompliance(Self & self, const ResidualVectorType & vector, ConstraintSelectionType sel)
216 {
217 switch (sel)
218 {
219 case ConstraintSelectionType::CURRENT:
220 return self.setCompliance(vector, CurrentSelection());
221 case ConstraintSelectionType::MAXIMAL:
222 return self.setCompliance(vector, MaximalSelection());
223 }
224 }
225
226 static ResidualVectorType retrieveCompliance(const Self & self, ConstraintSelectionType sel)
227 {
228 switch (sel)
229 {
230 case ConstraintSelectionType::CURRENT: {
231 ResidualVectorType rescs(self.residualSize(CurrentSelection()));
232 self.retrieveCompliance(rescs, CurrentSelection());
233 return rescs;
234 }
235 case ConstraintSelectionType::MAXIMAL: {
236 ResidualVectorType resms(self.residualSize(MaximalSelection()));
237 self.retrieveCompliance(resms, MaximalSelection());
238 return resms;
239 }
240 default:
241 PINOCCHIO_UNREACHABLE();
242 }
243 }
244
245 static void setBaumgarteCorrectorParameters(
246 Self & self, const BaumgarteCorrectorParameters & copy, ConstraintSelectionType sel)
247 {
248 switch (sel)
249 {
250 case ConstraintSelectionType::CURRENT:
251 return self.setBaumgarteCorrectorParameters(copy, CurrentSelection());
252 case ConstraintSelectionType::MAXIMAL:
253 return self.setBaumgarteCorrectorParameters(copy, MaximalSelection());
254 }
255 }
256
257 static void calc(
258 const Self & self, const Model & model, const Data & data, ConstraintData & constraint_data)
259 {
260 self.calc(model, data, constraint_data);
261 }
262
263 static context::MatrixXs jacobianMatrixProduct(
264 const Self & self,
265 const Model & model,
266 const Data & data,
267 const ConstraintData & constraint_data,
268 const context::RefConstMatrixXs & matrix)
269 {
270 context::MatrixXs res = context::MatrixXs::Zero(self.residualSize(), matrix.cols());
271 self.jacobianMatrixProduct(model, data, constraint_data, matrix, res);
272 return res;
273 }
274
275 static context::MatrixXs jacobianTransposeMatrixProduct(
276 const Self & self,
277 const Model & model,
278 const Data & data,
279 const ConstraintData & constraint_data,
280 const context::RefConstMatrixXs & matrix)
281 {
282 context::MatrixXs res = context::MatrixXs::Zero(model.nv, matrix.cols());
283 self.jacobianTransposeMatrixProduct(model, data, constraint_data, matrix, res);
284 return res;
285 }
286
287 static context::VectorXs mapConstraintForceToJointSpace(
288 const Self & self,
289 const Model & model,
290 const Data & data,
291 const ConstraintData & cdata,
292 const context::VectorXs & constraint_forces,
293 ForceVector & joint_forces,
294 ReferenceFrame rf)
295 {
296 context::VectorXs joint_torques = context::VectorXs::Zero(model.nv);
297 switch (rf)
298 {
299 case WORLD:
300 self.mapConstraintForceToJointSpace(
301 model, data, cdata, constraint_forces, joint_forces, joint_torques, WorldFrameTag());
302 break;
303 case LOCAL:
304 self.mapConstraintForceToJointSpace(
305 model, data, cdata, constraint_forces, joint_forces, joint_torques, LocalFrameTag());
306 break;
307 case LOCAL_WORLD_ALIGNED:
308 self.mapConstraintForceToJointSpace(
309 model, data, cdata, constraint_forces, joint_forces, joint_torques,
310 LocalWorldAlignedFrameTag());
311 break;
312 }
313 return joint_torques;
314 }
315
316 static context::VectorXs mapJointSpaceToConstraintMotion(
317 const Self & self,
318 const Model & model,
319 const Data & data,
320 const ConstraintData & cdata,
321 const MotionVector & joint_motions,
322 const context::VectorXs & joint_generalized_velocity,
323 ReferenceFrame rf)
324 {
325 context::VectorXs constraint_motions = context::VectorXs::Zero(self.residualSize());
326 switch (rf)
327 {
328 case WORLD:
329 self.mapJointSpaceToConstraintMotion(
330 model, data, cdata, joint_motions, joint_generalized_velocity, constraint_motions,
331 WorldFrameTag());
332 break;
333 case LOCAL:
334 self.mapJointSpaceToConstraintMotion(
335 model, data, cdata, joint_motions, joint_generalized_velocity, constraint_motions,
336 LocalFrameTag());
337 break;
338 case LOCAL_WORLD_ALIGNED:
339 self.mapJointSpaceToConstraintMotion(
340 model, data, cdata, joint_motions, joint_generalized_velocity, constraint_motions,
341 LocalWorldAlignedFrameTag());
342 break;
343 }
344 return constraint_motions;
345 }
346
347 static void appendCouplingConstraintInertias(
348 const Self & self,
349 const Model & model,
350 Data & data,
351 const ConstraintData & constraint_data,
352 const context::VectorXs & diagonal_constraint_inertia,
353 ReferenceFrame rf)
354 {
355 switch (rf)
356 {
357 case WORLD:
358 self.appendCouplingConstraintInertias(
359 model, data, constraint_data, diagonal_constraint_inertia, WorldFrameTag());
360 break;
361 case LOCAL:
362 self.appendCouplingConstraintInertias(
363 model, data, constraint_data, diagonal_constraint_inertia, LocalFrameTag());
364 break;
365 case LOCAL_WORLD_ALIGNED:
366 self.appendCouplingConstraintInertias(
367 model, data, constraint_data, diagonal_constraint_inertia, LocalWorldAlignedFrameTag());
368 break;
369 }
370 }
371 };
372 } // namespace python
373} // namespace pinocchio
Main pinocchio namespace.
Definition treeview.dox:11
void copy(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &origin, DataTpl< Scalar, Options, JointCollectionTpl > &dest, KinematicLevel kinematic_level)
Copy part of the data from origin to dest. Template parameter can be used to select at which differen...