pinocchio 4.1.0
A fast and flexible implementation of Rigid Body Dynamics algorithms and their analytical derivatives
Loading...
Searching...
No Matches
model.hpp
1//
2// Copyright (c) 2015-2018 CNRS
3// Copyright (c) 2018-2025 INRIA
4// Copyright (c) 2015 Wandercraft, 86 rue de Paris 91400 Orsay, France.
5//
6
7#pragma once
8
9#include <eigenpy/eigen-to-python.hpp>
10#include <eigenpy/copyable.hpp>
11
12#include "pinocchio/multibody.hpp"
13#include "pinocchio/serialization.hpp"
14
15#include <boost/python/overloads.hpp>
16#include <eigenpy/memory.hpp>
17#include <eigenpy/exception.hpp>
18
19#include "pinocchio/algorithm/check.hpp"
20
21#include "pinocchio/bindings/python/utils/cast.hpp"
22#include "pinocchio/bindings/python/utils/macros.hpp"
23#include "pinocchio/bindings/python/utils/printable.hpp"
24#include "pinocchio/bindings/python/utils/std-map.hpp"
25#include "pinocchio/bindings/python/utils/pickle.hpp"
26#include "pinocchio/bindings/python/utils/pickle-map.hpp"
27#include "pinocchio/bindings/python/utils/std-vector.hpp"
28#include "pinocchio/bindings/python/serialization/serializable.hpp"
29
30namespace pinocchio
31{
32 namespace python
33 {
34 namespace bp = boost::python;
35
36 template<typename Model>
37 struct ModelPythonVisitor : public bp::def_visitor<ModelPythonVisitor<Model>>
38 {
39 public:
40 typedef typename Model::Scalar Scalar;
41
42 typedef typename Model::Index Index;
43 typedef typename Model::JointIndex JointIndex;
44 typedef typename Model::JointModel JointModel;
45 typedef typename JointModel::JointModelVariant JointModelVariant;
46 typedef typename Model::FrameIndex FrameIndex;
47 typedef typename Model::IndexVector IndexVector;
48
49 typedef typename Model::SE3 SE3;
50 typedef typename Model::Motion Motion;
51 typedef typename Model::Force Force;
52 typedef typename Model::Frame Frame;
53 typedef typename Model::Inertia Inertia;
54
55 typedef typename Model::Data Data;
56
57 typedef typename Model::VectorXs VectorXs;
58
59 public:
60 /* --- Exposing C++ API to python through the handler ----------------- */
61 template<class PyClass>
62 void visit(PyClass & cl) const
63 {
64 cl.def(bp::init<>(bp::arg("self"), "Default constructor. Constructs an empty model."))
65 .def(bp::init<const Model &>((bp::arg("self"), bp::arg("clone")), "Copy constructor"))
66
67 // Class Members
68 .add_property("nq", &Model::nq, "Dimension of the configuration vector representation.")
69 .add_property("nv", &Model::nv, "Dimension of the velocity vector space.")
70 .add_property("nvExtended", &Model::nvExtended, "Dimension of the jacobian matrix space.")
71 .add_property("njoints", &Model::njoints, "Number of joints.")
72 .add_property("nbodies", &Model::nbodies, "Number of bodies.")
73 .add_property("nframes", &Model::nframes, "Number of frames.")
74 .add_property(
75 "inertias", &Model::inertias, "Vector of spatial inertias supported by each joint.")
76 .def_readwrite(
77 "jointPlacements", &Model::jointPlacements,
78 "Vector of joint placements: placement of a joint *i* wrt its parent joint frame.")
79 .add_property("joints", &Model::joints, "Vector of joint models.")
80 .add_property(
81 "idx_qs", &Model::idx_qs,
82 "Vector of starting index of the *i*th joint in the configuration space.")
83 .add_property(
84 "nqs", &Model::nqs, "Vector of dimension of the joint configuration subspace.")
85 .add_property(
86 "idx_vs", &Model::idx_vs,
87 "Starting index of the *i*th joint in the tangent configuration space.")
88 .add_property("nvs", &Model::nvs, "Dimension of the *i*th joint tangent subspace.")
89 .add_property(
90 "idx_vExtendeds", &Model::idx_vExtendeds,
91 "Starting index of the *i*th joint in the jacobian space.")
92 .add_property(
93 "nvExtendeds", &Model::nvExtendeds, "Dimension of the *i*th joint jacobian subspace.")
94 .add_property(
95 "parents", &Model::parents,
96 "Vector of parent joint indexes. The parent of joint *i*, denoted *li*, corresponds to "
97 "li==parents[i].")
98 .add_property(
99 "children", &Model::children,
100 "Vector of children index. Chidren of the *i*th joint, denoted *mu(i)* corresponds to "
101 "the set (i==parents[k] for k in mu(i)).")
102 .add_property("names", &Model::names, "Name of the joints.")
103 .def_readwrite("name", &Model::name, "Name of the model.")
104 .def_readwrite(
105 "referenceConfigurations", &Model::referenceConfigurations,
106 "Map of reference configurations, indexed by user given names.")
107
108 .def_readwrite("armature", &Model::armature, "Armature vector.")
109 .def_readwrite(
110 "rotorInertia", &Model::rotorInertia, "Vector of rotor inertia parameters.")
111 .def_readwrite(
112 "rotorGearRatio", &Model::rotorGearRatio, "Vector of rotor gear ratio parameters.")
113 .def_readwrite(
114 "friction", &Model::upperDryFrictionLimit,
115 "Deprecated member. Vector of joint friction parameters.")
116 .def_readwrite(
117 "upperDryFrictionLimit", &Model::upperDryFrictionLimit,
118 "Vector of maximum joint friction.")
119 .def_readwrite(
120 "lowerDryFrictionLimit", &Model::lowerDryFrictionLimit,
121 "Vector of minimum joint friction.")
122 .def_readwrite("damping", &Model::damping, "Vector of joint damping parameters.")
123 .def_readwrite(
124 "effortLimit", &Model::upperEffortLimit, "Deprecated member. Joint max effort.")
125 .def_readwrite("upperEffortLimit", &Model::upperEffortLimit, "Joint max effort.")
126 .def_readwrite("lowerEffortLimit", &Model::lowerEffortLimit, "Joint min effort.")
127 .def_readwrite(
128 "velocityLimit", &Model::upperVelocityLimit, "Deprecated member. Joint max velocity.")
129 .def_readwrite("lowerVelocityLimit", &Model::lowerVelocityLimit, "Joint min velocity.")
130 .def_readwrite("upperVelocityLimit", &Model::upperVelocityLimit, "Joint max velocity.")
131 .def_readwrite(
132 "lowerPositionLimit", &Model::lowerPositionLimit, "Limit for joint lower position.")
133 .def_readwrite(
134 "upperPositionLimit", &Model::upperPositionLimit, "Limit for joint upper position.")
135 .def_readwrite(
136 "positionLimitMargin", &Model::positionLimitMargin, "Margin for joint position limit.")
137
138 .def_readwrite("frames", &Model::frames, "Vector of frames contained in the model.")
139
140 .def_readwrite(
141 "supports", &Model::supports,
142 "Vector of supports. supports[j] corresponds to the list of joints on the path "
143 "between\n"
144 "the current *j* to the root of the kinematic tree.")
145
146 .def_readwrite(
147 "mimic_joint_supports", &Model::mimic_joint_supports,
148 "Vector of mimic supports joints. "
149 "mimic_joint_supports[j] corresponds to the vector of mimic joints indices located on "
150 "the path "
151 "between joint *j* and \"universe\". The first element of mimic_joint_supports[j] is "
152 "\"universe\". "
153 "If *j* is a mimic, the last element is the index of joint *j* itself")
154
155 .def_readwrite(
156 "subtrees", &Model::subtrees,
157 "Vector of subtrees. subtree[j] corresponds to the subtree supported by the joint j.")
158
159 .def_readwrite(
160 "sparsity_pattern_vector", &Model::sparsity_pattern_vector,
161 "Sparsity pattern for each joint, indexed by joint_id. "
162 "sparsity_pattern_vector[i] is a boolean vector of size nv indicating which columns "
163 "of the Jacobian are nonzero for joint i.")
164
165 .def_readwrite(
166 "span_indexes_vector", &Model::span_indexes_vector,
167 "Colwise span indexes for each joint, indexed by joint_id. "
168 "span_indexes_vector[i] lists the column indexes of nonzero entries for joint i.")
169
170 .def_readwrite(
171 "mimicking_joints", &Model::mimicking_joints,
172 "Vector of mimicking joints in the tree (with type MimicTpl)")
173
174 .def_readwrite(
175 "mimicked_joints", &Model::mimicked_joints,
176 "Vector of mimicked joints in the tree (can be any joint type)")
177
178 .def_readwrite(
179 "gravity", &Model::gravity,
180 "Motion vector corresponding to the gravity field expressed in the world Frame.")
181
182 // Class Methods
183 .def(
184 "addJoint", &ModelPythonVisitor::addJoint0,
185 bp::args("self", "parent_id", "joint_model", "joint_placement", "joint_name"),
186 "Adds a joint to the kinematic tree. The joint is defined by its placement relative to "
187 "its parent joint and its name.")
188 .def(
189 "addJoint", &ModelPythonVisitor::addJoint1,
190 bp::args(
191 "self", "parent_id", "joint_model", "joint_placement", "joint_name", "max_effort",
192 "max_velocity", "min_config", "max_config"),
193 "Adds a joint to the kinematic tree with given bounds. The joint is defined by its "
194 "placement relative to its parent joint and its name."
195 "This signature also takes as input effort, velocity limits as well as the bounds on "
196 "the joint configuration.")
197 .def(
198 "addJoint", &ModelPythonVisitor::addJoint2,
199 bp::args(
200 "self", "parent_id", "joint_model", "joint_placement", "joint_name", "min_effort",
201 "max_effort", "min_velocity", "max_velocity", "min_config", "max_config",
202 "min_friction", "max_friction", "damping"),
203 "Adds a joint to the kinematic tree with given bounds. The joint is defined by its "
204 "placement relative to its parent joint and its name.\n"
205 "This signature also takes as input effort, velocity limits as well as the bounds on "
206 "the joint configuration.\n"
207 "The user should also provide the friction and damping related to the joint.")
208 .def(
209 "addJoint", &ModelPythonVisitor::addJoint3,
210 bp::args(
211 "self", "parent_id", "joint_model", "joint_placement", "joint_name", "min_effort",
212 "max_effort", "min_velocity", "max_velocity", "min_config", "max_config",
213 "config_limit_margin", "min_friction", "max_friction", "damping"),
214 "Adds a joint to the kinematic tree with given bounds. The joint is defined by its "
215 "placement relative to its parent joint and its name.\n"
216 "This signature also takes as input effort, velocity limits, bounds on "
217 "the joint configuration as well as margin on these bounds.\n"
218 "The user should also provide the friction and damping related to the joint.")
219 .def(
220 "addJointFrame", &Model::addJointFrame,
221 (bp::arg("self"), bp::arg("joint_id"), bp::arg("frame_id") = 0),
222 "Add the joint provided by its joint_id as a frame to the frame tree.\n"
223 "The frame_id may be optionally provided.")
224 .def(
225 "appendBodyToJoint", &Model::appendBodyToJoint,
226 bp::args("self", "joint_id", "body_inertia", "body_placement"),
227 "Appends a body to the joint given by its index. The body is defined by its inertia, "
228 "its relative placement regarding to the joint and its name.")
229
230 .def(
231 "addBodyFrame", &Model::addBodyFrame,
232 bp::args("self", "body_name", "parentJoint", "body_placement", "previous_frame"),
233 "add a body to the frame tree")
234 .def(
235 "getBodyId", &Model::getBodyId, bp::args("self", "name"),
236 "Return the index of a frame of type BODY given by its name")
237 .def(
238 "existBodyName", &Model::existBodyName, bp::args("self", "name"),
239 "Check if a frame of type BODY exists, given its name")
240 .def(
241 "getJointId", &Model::getJointId, bp::args("self", "name"),
242 "Return the index of a joint given by its name")
243 .def(
244 "existJointName", &Model::existJointName, bp::args("self", "name"),
245 "Check if a joint given by its name exists")
246
247 .def(
248 "getFrameId", &Model::getFrameId,
249 (bp::arg("self"), bp::arg("name"),
250 bp::arg("type") = (FrameType)(JOINT | FIXED_JOINT | BODY | OP_FRAME | SENSOR)),
251 "Returns the index of the frame given by its name and its type."
252 "If the frame is not in the frames vector, it returns the current size of the frames "
253 "vector.")
254
255 .def(
256 "existFrame", &Model::existFrame,
257 (bp::arg("self"), bp::arg("name"),
258 bp::arg("type") = (FrameType)(JOINT | FIXED_JOINT | BODY | OP_FRAME | SENSOR)),
259 "Returns true if the frame given by its name exists inside the Model with the given "
260 "type.")
261
262 .def(
263 "addFrame", &Model::addFrame,
264 (bp::arg("self"), bp::arg("frame"), bp::arg("append_inertia") = true),
265 "Add a frame to the vector of frames. If append_inertia set to True, "
266 "the inertia value contained in frame will be added to the inertia supported by the "
267 "parent joint.")
268
269 .def(
270 "createData", &Model::createData, bp::arg("self"),
271 "Create a Data object for the given model.")
272
273 .def(
274 "check", (bool (Model::*)(const Data &) const) & Model::check, bp::args("self", "data"),
275 "Check consistency of data wrt model.")
276
277 .def(
278 "hasConfigurationLimit", &Model::hasConfigurationLimit, bp::args("self"),
279 "Returns list of boolean if joints have configuration limit.")
280 .def(
281 "hasConfigurationLimitInTangent", &Model::hasConfigurationLimitInTangent,
282 bp::args("self"),
283 "Returns list of boolean if joints have configuration limit in tangent space.")
284 .def(
285 "getChildJoints", &Model::getChildJoints, bp::args("self"),
286 "Returns a vector of the children joints of the kinematic tree..")
287
288#ifndef PINOCCHIO_PYTHON_SKIP_COMPARISON_OPERATIONS
289
290 .def(bp::self == bp::self)
291 .def(bp::self != bp::self)
292#endif
293
294 .PINOCCHIO_ADD_STATIC_PROPERTY_READONLY_BYVALUE(
295 Model, gravity981, "Default gravity field value on the Earth.");
296
297 bp::register_ptr_to_python<std::shared_ptr<Model>>();
298 }
299
300 static JointIndex addJoint0(
301 Model & model,
302 JointIndex parent_id,
303 const JointModel & jmodel,
304 const SE3 & joint_placement,
305 const std::string & joint_name)
306 {
307 return model.addJoint(parent_id, jmodel, joint_placement, joint_name);
308 }
309
310 static JointIndex addJoint1(
311 Model & model,
312 JointIndex parent_id,
313 const JointModel & jmodel,
314 const SE3 & joint_placement,
315 const std::string & joint_name,
316 const VectorXs & max_effort,
317 const VectorXs & max_velocity,
318 const VectorXs & min_config,
319 const VectorXs & max_config)
320 {
321 return model.addJoint(
322 parent_id, jmodel, joint_placement, joint_name, max_effort, max_velocity, min_config,
323 max_config);
324 }
325
326 static JointIndex addJoint2(
327 Model & model,
328 JointIndex parent_id,
329 const JointModel & jmodel,
330 const SE3 & joint_placement,
331 const std::string & joint_name,
332 const VectorXs & min_effort,
333 const VectorXs & max_effort,
334 const VectorXs & min_velocity,
335 const VectorXs & max_velocity,
336 const VectorXs & min_config,
337 const VectorXs & max_config,
338 const VectorXs & min_friction,
339 const VectorXs & max_friction,
340 const VectorXs & damping)
341 {
342 return model.addJoint(
343 parent_id, jmodel, joint_placement, joint_name, min_effort, max_effort, min_velocity,
344 max_velocity, min_config, max_config, min_friction, max_friction, damping);
345 }
346
347 static JointIndex addJoint3(
348 Model & model,
349 JointIndex parent_id,
350 const JointModel & jmodel,
351 const SE3 & joint_placement,
352 const std::string & joint_name,
353 const VectorXs & min_effort,
354 const VectorXs & max_effort,
355 const VectorXs & min_velocity,
356 const VectorXs & max_velocity,
357 const VectorXs & min_config,
358 const VectorXs & max_config,
359 const VectorXs & config_limit_margin,
360 const VectorXs & min_friction,
361 const VectorXs & max_friction,
362 const VectorXs & damping)
363 {
364 return model.addJoint(
365 parent_id, jmodel, joint_placement, joint_name, min_effort, max_effort, min_velocity,
366 max_velocity, min_config, max_config, config_limit_margin, min_friction, max_friction,
367 damping);
368 }
369
380 template<typename T>
381 static Index index(std::vector<T> const & x, typename std::vector<T>::value_type const & v)
382 {
383 Index i = 0;
384 for (typename std::vector<T>::const_iterator it = x.begin(); it != x.end(); ++it, ++i)
385 {
386 if (*it == v)
387 {
388 return i;
389 }
390 }
391 return x.size();
392 }
393
394 /* --- Expose --------------------------------------------------------- */
395 static void expose()
396 {
397 typedef typename Model::ConfigVectorMap ConfigVectorMap;
398 typedef bp::map_indexing_suite<ConfigVectorMap, false> map_indexing_suite;
399 StdVectorPythonVisitor<std::vector<Index>, true>::expose("StdVec_Index");
400 serialize<std::vector<Index>>();
401 StdVectorPythonVisitor<std::vector<IndexVector>>::expose("StdVec_IndexVector");
402 serialize<std::vector<IndexVector>>();
403 StdVectorPythonVisitor<std::vector<std::string>, true>::expose("StdVec_StdString");
404 StdVectorPythonVisitor<std::vector<bool>, true>::expose("StdVec_Bool");
405 StdVectorPythonVisitor<std::vector<Scalar>, true>::expose("StdVec_Scalar");
406 StdVectorPythonVisitor<typename Model::EigenIndexVector, true>::expose("StdVec_EigenIndex");
407 StdVectorPythonVisitor<typename Model::VectorOfEigenIndexVector>::expose(
408 "StdVec_EigenIndexVector");
409 StdVectorPythonVisitor<typename Model::VectorOfBooleanVector>::expose(
410 "StdVec_BooleanVector");
411
412#if defined(PINOCCHIO_PYTHON_INTERFACE_MAIN_MODULE)
413 bp::scope().attr("StdVec_Double") = bp::scope().attr("StdVec_Scalar"); // alias
414#endif
415
416 serialize<std::vector<std::string>>();
417 serialize<std::vector<bool>>();
418#ifndef PINOCCHIO_PYTHON_NO_SERIALIZATION
419 serialize<std::vector<Scalar>>();
420#endif
421 bp::class_<typename Model::ConfigVectorMap>("StdMap_String_VectorXd")
422 .def(map_indexing_suite())
425
426 bp::class_<Model>("Model", "Articulated Rigid Body model", bp::no_init)
427 .def(ModelPythonVisitor())
428 .def(CastVisitor<Model>())
432 .def(::eigenpy::CopyableVisitor<Model>())
433#ifndef PINOCCHIO_PYTHON_NO_SERIALIZATION
435#endif
436 ;
437 }
438 };
439
440 } // namespace python
441} // namespace pinocchio
Main pinocchio namespace.
Definition treeview.dox:11
Add the Python method cast.
Definition cast.hpp:23
static Index index(std::vector< T > const &x, typename std::vector< T >::value_type const &v)
Provide equivalent to python list index function for vectors.
Definition model.hpp:381
Create a pickle interface for the std::map and aligned map.
Set the Python method str and repr to use the overloading operator<<.
Definition printable.hpp:21