pinocchio  3.9.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-2023 CNRS INRIA
3// Copyright (c) 2015 Wandercraft, 86 rue de Paris 91400 Orsay, France.
4//
5
6#ifndef __pinocchio_python_multibody_model_hpp__
7#define __pinocchio_python_multibody_model_hpp__
8
9#include <eigenpy/eigen-to-python.hpp>
10
11#include "pinocchio/multibody/model.hpp"
12#include "pinocchio/serialization/model.hpp"
13
14#include <boost/python/overloads.hpp>
15#include <eigenpy/memory.hpp>
16#include <eigenpy/exception.hpp>
17
18#include "pinocchio/algorithm/check.hpp"
19
20#include "pinocchio/bindings/python/utils/cast.hpp"
21#include "pinocchio/bindings/python/utils/macros.hpp"
22#include "pinocchio/bindings/python/utils/printable.hpp"
23#include "pinocchio/bindings/python/utils/copyable.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
30#if EIGENPY_VERSION_AT_MOST(2, 8, 1)
31EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(pinocchio::Model)
32#endif
33
34namespace pinocchio
35{
36 namespace python
37 {
38 namespace bp = boost::python;
39
40 template<typename Model>
41 struct ModelPythonVisitor : public bp::def_visitor<ModelPythonVisitor<Model>>
42 {
43 public:
44 typedef typename Model::Scalar Scalar;
45
46 typedef typename Model::Index Index;
47 typedef typename Model::JointIndex JointIndex;
48 typedef typename Model::JointModel JointModel;
49 typedef typename JointModel::JointModelVariant JointModelVariant;
50 typedef typename Model::FrameIndex FrameIndex;
51 typedef typename Model::IndexVector IndexVector;
52
53 typedef typename Model::SE3 SE3;
54 typedef typename Model::Motion Motion;
55 typedef typename Model::Force Force;
56 typedef typename Model::Frame Frame;
57 typedef typename Model::Inertia Inertia;
58
59 typedef typename Model::Data Data;
60
61 typedef typename Model::VectorXs VectorXs;
62
63 public:
64 /* --- Exposing C++ API to python through the handler ----------------- */
65 template<class PyClass>
66 void visit(PyClass & cl) const
67 {
68 cl.def(bp::init<>(bp::arg("self"), "Default constructor. Constructs an empty model."))
69 .def(bp::init<const Model &>((bp::arg("self"), bp::arg("clone")), "Copy constructor"))
70
71 // Class Members
72 .add_property("nq", &Model::nq, "Dimension of the configuration vector representation.")
73 .add_property("nv", &Model::nv, "Dimension of the velocity vector space.")
74 .add_property("nvExtended", &Model::nvExtended, "Dimension of the jacobian matrix space.")
75 .add_property("njoints", &Model::njoints, "Number of joints.")
76 .add_property("nbodies", &Model::nbodies, "Number of bodies.")
77 .add_property("nframes", &Model::nframes, "Number of frames.")
78 .add_property(
79 "inertias", &Model::inertias, "Vector of spatial inertias supported by each joint.")
80 .def_readwrite(
81 "jointPlacements", &Model::jointPlacements,
82 "Vector of joint placements: placement of a joint *i* wrt its parent joint frame.")
83 .add_property("joints", &Model::joints, "Vector of joint models.")
84 .add_property(
85 "idx_qs", &Model::idx_qs,
86 "Vector of starting index of the *i*th joint in the configuration space.")
87 .add_property(
88 "nqs", &Model::nqs, "Vector of dimension of the joint configuration subspace.")
89 .add_property(
90 "idx_vs", &Model::idx_vs,
91 "Starting index of the *i*th joint in the tangent configuration space.")
92 .add_property("nvs", &Model::nvs, "Dimension of the *i*th joint tangent subspace.")
93 .add_property(
94 "idx_vExtendeds", &Model::idx_vExtendeds,
95 "Starting index of the *i*th joint in the jacobian space.")
96 .add_property(
97 "nvExtendeds", &Model::nvExtendeds, "Dimension of the *i*th joint jacobian subspace.")
98 .add_property(
99 "parents", &Model::parents,
100 "Vector of parent joint indexes. The parent of joint *i*, denoted *li*, "
101 "corresponds to li==parents[i].")
102 .add_property(
103 "children", &Model::children,
104 "Vector of children index. Chidren of the *i*th joint, denoted *mu(i)* "
105 "corresponds to the set (i==parents[k] for k in mu(i)).")
106 .add_property("names", &Model::names, "Name of the joints.")
107 .def_readwrite("name", &Model::name, "Name of the model.")
108 .def_readwrite(
109 "referenceConfigurations", &Model::referenceConfigurations,
110 "Map of reference configurations, indexed by user given names.")
111
112 .def_readwrite("armature", &Model::armature, "Armature vector.")
113 .def_readwrite(
114 "rotorInertia", &Model::rotorInertia, "Vector of rotor inertia parameters.")
115 .def_readwrite(
116 "rotorGearRatio", &Model::rotorGearRatio, "Vector of rotor gear ratio parameters.")
117 .def_readwrite("friction", &Model::friction, "Vector of joint friction parameters.")
118 .def_readwrite("damping", &Model::damping, "Vector of joint damping parameters.")
119 .def_readwrite("effortLimit", &Model::effortLimit, "Joint max effort.")
120 .def_readwrite("velocityLimit", &Model::velocityLimit, "Joint max velocity.")
121 .def_readwrite(
122 "lowerPositionLimit", &Model::lowerPositionLimit, "Limit for joint lower position.")
123 .def_readwrite(
124 "upperPositionLimit", &Model::upperPositionLimit, "Limit for joint upper position.")
125
126 .def_readwrite("frames", &Model::frames, "Vector of frames contained in the model.")
127
128 .def_readwrite(
129 "supports", &Model::supports,
130 "Vector of supports. supports[j] corresponds to the list of joints on the "
131 "path between\n"
132 "the current *j* to the root of the kinematic tree.")
133
134 .def_readwrite(
135 "mimic_joint_supports", &Model::mimic_joint_supports,
136 "Vector of mimic supports joints. "
137 "mimic_joint_supports[j] corresponds to the vector of mimic joints indices located on "
138 "the path "
139 "between joint *j* and \"universe\". The first element of mimic_joint_supports[j] is "
140 "\"universe\". "
141 "If *j* is a mimic, the last element is the index of joint *j* itself")
142
143 .def_readwrite(
144 "subtrees", &Model::subtrees,
145 "Vector of subtrees. subtree[j] corresponds to the subtree supported by the joint j.")
146
147 .def_readwrite(
148 "mimicking_joints", &Model::mimicking_joints,
149 "Vector of mimicking joints in the tree (with type MimicTpl)")
150
151 .def_readwrite(
152 "mimicked_joints", &Model::mimicked_joints,
153 "Vector of mimicked joints in the tree (can be any joint type)")
154
155 .def_readwrite(
156 "gravity", &Model::gravity,
157 "Motion vector corresponding to the gravity field expressed in the world Frame.")
158
159 // Class Methods
160 .def(
161 "addJoint", &ModelPythonVisitor::addJoint0,
162 bp::args("self", "parent_id", "joint_model", "joint_placement", "joint_name"),
163 "Adds a joint to the kinematic tree. The joint is defined by its placement relative "
164 "to its parent joint and its name.")
165 .def(
166 "addJoint", &ModelPythonVisitor::addJoint1,
167 bp::args(
168 "self", "parent_id", "joint_model", "joint_placement", "joint_name", "max_effort",
169 "max_velocity", "min_config", "max_config"),
170 "Adds a joint to the kinematic tree with given bounds. The joint is defined by its "
171 "placement relative to its parent joint and its name."
172 "This signature also takes as input effort, velocity limits as well as the bounds "
173 "on the joint configuration.")
174 .def(
175 "addJoint", &ModelPythonVisitor::addJoint2,
176 bp::args(
177 "self", "parent_id", "joint_model", "joint_placement", "joint_name", "max_effort",
178 "max_velocity", "min_config", "max_config", "friction", "damping"),
179 "Adds a joint to the kinematic tree with given bounds. The joint is defined by its "
180 "placement relative to its parent joint and its name.\n"
181 "This signature also takes as input effort, velocity limits as well as the bounds "
182 "on the joint configuration.\n"
183 "The user should also provide the friction and damping related to the joint.")
184 .def(
185 "addJointFrame", &Model::addJointFrame,
186 (bp::arg("self"), bp::arg("joint_id"), bp::arg("frame_id") = 0),
187 "Add the joint provided by its joint_id as a frame to the frame tree.\n"
188 "The frame_id may be optionally provided.")
189 .def(
190 "appendBodyToJoint", &Model::appendBodyToJoint,
191 bp::args("self", "joint_id", "body_inertia", "body_placement"),
192 "Appends a body to the joint given by its index. The body is defined by its "
193 "inertia, its relative placement regarding to the joint and its name.")
194
195 .def(
196 "addBodyFrame", &Model::addBodyFrame,
197 bp::args("self", "body_name", "parentJoint", "body_placement", "previous_frame"),
198 "add a body to the frame tree")
199 .def(
200 "getBodyId", &Model::getBodyId, bp::args("self", "name"),
201 "Return the index of a frame of type BODY given by its name")
202 .def(
203 "existBodyName", &Model::existBodyName, bp::args("self", "name"),
204 "Check if a frame of type BODY exists, given its name")
205 .def(
206 "getJointId", &Model::getJointId, bp::args("self", "name"),
207 "Return the index of a joint given by its name")
208 .def(
209 "existJointName", &Model::existJointName, bp::args("self", "name"),
210 "Check if a joint given by its name exists")
211
212 .def(
213 "getFrameId", &Model::getFrameId,
214 (bp::arg("self"), bp::arg("name"),
215 bp::arg("type") = (FrameType)(JOINT | FIXED_JOINT | BODY | OP_FRAME | SENSOR)),
216 "Returns the index of the frame given by its name and its type."
217 "If the frame is not in the frames vector, it returns the current size of the "
218 "frames vector.")
219
220 .def(
221 "existFrame", &Model::existFrame,
222 (bp::arg("self"), bp::arg("name"),
223 bp::arg("type") = (FrameType)(JOINT | FIXED_JOINT | BODY | OP_FRAME | SENSOR)),
224 "Returns true if the frame given by its name exists inside the Model with the given "
225 "type.")
226
227 .def(
228 "addFrame", &Model::addFrame,
229 (bp::arg("self"), bp::arg("frame"), bp::arg("append_inertia") = true),
230 "Add a frame to the vector of frames. If append_inertia set to True, "
231 "the inertia value contained in frame will be added to the inertia supported by the "
232 "parent joint.")
233
234 .def(
235 "createData", &ModelPythonVisitor::createData, bp::arg("self"),
236 "Create a Data object for the given model.")
237
238 .def(
239 "check", (bool(Model::*)(const Data &) const) & Model::check, bp::args("self", "data"),
240 "Check consistency of data wrt model.")
241
242 .def(
243 "hasConfigurationLimit", &Model::hasConfigurationLimit, bp::args("self"),
244 "Returns list of boolean if joints have configuration limit.")
245 .def(
246 "hasConfigurationLimitInTangent", &Model::hasConfigurationLimitInTangent,
247 bp::args("self"),
248 "Returns list of boolean if joints have configuration limit in tangent space .")
249
250#ifndef PINOCCHIO_PYTHON_SKIP_COMPARISON_OPERATIONS
251
252 .def(bp::self == bp::self)
253 .def(bp::self != bp::self)
254#endif
255
256 .PINOCCHIO_ADD_STATIC_PROPERTY_READONLY_BYVALUE(
257 Model, gravity981, "Default gravity field value on the Earth.");
258
259 bp::register_ptr_to_python<std::shared_ptr<Model>>();
260 }
261
262 static JointIndex addJoint0(
263 Model & model,
264 JointIndex parent_id,
265 const JointModel & jmodel,
266 const SE3 & joint_placement,
267 const std::string & joint_name)
268 {
269 return model.addJoint(parent_id, jmodel, joint_placement, joint_name);
270 }
271
272 static JointIndex addJoint1(
273 Model & model,
274 JointIndex parent_id,
275 const JointModel & jmodel,
276 const SE3 & joint_placement,
277 const std::string & joint_name,
278 const VectorXs & max_effort,
279 const VectorXs & max_velocity,
280 const VectorXs & min_config,
281 const VectorXs & max_config)
282 {
283 return model.addJoint(
284 parent_id, jmodel, joint_placement, joint_name, max_effort, max_velocity, min_config,
285 max_config);
286 }
287
288 static JointIndex addJoint2(
289 Model & model,
290 JointIndex parent_id,
291 const JointModel & jmodel,
292 const SE3 & joint_placement,
293 const std::string & joint_name,
294 const VectorXs & max_effort,
295 const VectorXs & max_velocity,
296 const VectorXs & min_config,
297 const VectorXs & max_config,
298 const VectorXs & friction,
299 const VectorXs & damping)
300 {
301 return model.addJoint(
302 parent_id, jmodel, joint_placement, joint_name, max_effort, max_velocity, min_config,
303 max_config, friction, damping);
304 }
305
306 static Data createData(const Model & model)
307 {
308 return Data(model);
309 }
310
321 template<typename T>
322 static Index index(std::vector<T> const & x, typename std::vector<T>::value_type const & v)
323 {
324 Index i = 0;
325 for (typename std::vector<T>::const_iterator it = x.begin(); it != x.end(); ++it, ++i)
326 {
327 if (*it == v)
328 {
329 return i;
330 }
331 }
332 return x.size();
333 }
334
335 /* --- Expose --------------------------------------------------------- */
336 static void expose()
337 {
338 typedef typename Model::ConfigVectorMap ConfigVectorMap;
339 typedef bp::map_indexing_suite<ConfigVectorMap, false> map_indexing_suite;
340 StdVectorPythonVisitor<std::vector<Index>, true>::expose("StdVec_Index");
341 serialize<std::vector<Index>>();
342 StdVectorPythonVisitor<std::vector<IndexVector>>::expose("StdVec_IndexVector");
343 serialize<std::vector<IndexVector>>();
344 StdVectorPythonVisitor<std::vector<std::string>, true>::expose("StdVec_StdString");
345 StdVectorPythonVisitor<std::vector<bool>, true>::expose("StdVec_Bool");
346 StdVectorPythonVisitor<std::vector<Scalar>, true>::expose("StdVec_Scalar");
347
348#if defined(PINOCCHIO_PYTHON_INTERFACE_MAIN_MODULE)
349 bp::scope().attr("StdVec_Double") = bp::scope().attr("StdVec_Scalar"); // alias
350#endif
351
352 serialize<std::vector<std::string>>();
353 serialize<std::vector<bool>>();
354#ifndef PINOCCHIO_PYTHON_NO_SERIALIZATION
355 serialize<std::vector<Scalar>>();
356#endif
357 bp::class_<typename Model::ConfigVectorMap>("StdMap_String_VectorXd")
358 .def(map_indexing_suite())
359 .def_pickle(PickleMap<typename Model::ConfigVectorMap>())
360 .def(details::overload_base_get_item_for_std_map<typename Model::ConfigVectorMap>());
361
362 bp::class_<Model>("Model", "Articulated Rigid Body model", bp::no_init)
363 .def(ModelPythonVisitor())
364 .def(CastVisitor<Model>())
365 .def(ExposeConstructorByCastVisitor<Model, ::pinocchio::Model>())
366 .def(SerializableVisitor<Model>())
367 .def(PrintableVisitor<Model>())
368 .def(CopyableVisitor<Model>())
369#ifndef PINOCCHIO_PYTHON_NO_SERIALIZATION
370 .def_pickle(PickleFromStringSerialization<Model>())
371#endif
372 ;
373 }
374 };
375
376 } // namespace python
377} // namespace pinocchio
378
379#endif // ifndef __pinocchio_python_multibody_model_hpp__
Main pinocchio namespace.
Definition treeview.dox:11
FrameType
Enum on the possible types of frames.
Definition frame.hpp:32
@ BODY
body frame: attached to the collision, inertial or visual properties of a link
Definition frame.hpp:36
@ SENSOR
sensor frame: defined in a sensor element
Definition frame.hpp:38
@ OP_FRAME
operational frame: user-defined frames that are defined at runtime
Definition frame.hpp:33
@ JOINT
joint frame: attached to the child body of a joint (a.k.a. child frame)
Definition frame.hpp:34
@ FIXED_JOINT
fixed joint frame: joint frame but for a fixed joint
Definition frame.hpp:35
FrameIndex addJointFrame(const JointIndex &joint_index, int previous_frame_index=-1)
FrameIndex getBodyId(const std::string &name) const
FrameIndex addBodyFrame(const std::string &body_name, const JointIndex &parentJoint, const SE3 &body_placement=SE3::Identity(), int parentFrame=-1)
JointIndex getJointId(const std::string &name) const
void appendBodyToJoint(const JointIndex joint_index, const Inertia &Y, const SE3 &body_placement=SE3::Identity())
bool existBodyName(const std::string &name) const
FrameIndex getFrameId(const std::string &name, const FrameType &type=(FrameType)(JOINT|FIXED_JOINT|BODY|OP_FRAME|SENSOR)) const
bool check(const AlgorithmCheckerBase< D > &checker=AlgorithmCheckerBase< D >()) const
Definition model.hpp:488
std::map< std::string, ConfigVectorType > ConfigVectorMap
Definition model.hpp:90
bool existFrame(const std::string &name, const FrameType &type=(FrameType)(JOINT|FIXED_JOINT|BODY|OP_FRAME|SENSOR)) const
bool existJointName(const std::string &name) const
FrameIndex addFrame(const Frame &frame, const bool append_inertia=true)