pinocchio 4.1.0
A fast and flexible implementation of Rigid Body Dynamics algorithms and their analytical derivatives
Loading...
Searching...
No Matches
force.hpp
1//
2// Copyright (c) 2015-2018 CNRS
3// Copyright (c) 2018-2025 INRIA
4// Copyright (c) 2016 Wandercraft, 86 rue de Paris 91400 Orsay, France.
5//
6
7#pragma once
8
9#include <eigenpy/eigenpy.hpp>
10#include <eigenpy/memory.hpp>
11#include <boost/python/tuple.hpp>
12#include <eigenpy/copyable.hpp>
13
14#include "pinocchio/spatial.hpp"
15
16#include "pinocchio/bindings/python/utils/cast.hpp"
17#include "pinocchio/bindings/python/utils/printable.hpp"
18
19namespace pinocchio
20{
21 namespace python
22 {
23 namespace bp = boost::python;
24
25 template<typename T>
26 struct call;
27
28 template<typename Scalar, int Options>
29 struct call<ForceTpl<Scalar, Options>>
30 {
31 typedef ForceTpl<Scalar, Options> Force;
32
33 static bool isApprox(
34 const Force & self,
35 const Force & other,
36 const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
37 {
38 return self.isApprox(other, prec);
39 }
40
41 static bool
42 isZero(const Force & self, const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
43 {
44 return self.isZero(prec);
45 }
46 };
47
48 template<typename Force>
49 struct ForcePythonVisitor : public boost::python::def_visitor<ForcePythonVisitor<Force>>
50 {
51 static constexpr int Options = traits<Force>::Options;
52
53 typedef typename Force::Vector6 Vector6;
54 typedef typename Force::Vector3 Vector3;
55 typedef typename Force::Scalar Scalar;
56
57 typedef typename Eigen::Map<Vector3> MapVector3;
58 typedef typename Eigen::Ref<Vector3> RefVector3;
59
60 template<class PyClass>
61 void visit(PyClass & cl) const
62 {
63 static const Scalar dummy_precision = Eigen::NumTraits<Scalar>::dummy_precision();
64 PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
65 PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_SELF_ASSIGN_OVERLOADED
66 cl.def(bp::init<>(bp::arg("self"), "Default constructor"))
67 .def(
68 bp::init<const Vector3 &, const Vector3 &>(
69 (bp::arg("self"), bp::arg("linear"), bp::arg("angular")),
70 "Initialize from linear and angular components of a Wrench vector (don't mix the "
71 "order)."))
72 .def(
73 bp::init<const Vector6 &>(
74 (bp::args("self", "array")), "Init from a vector 6 [force,torque]"))
75 .def(bp::init<const Force &>((bp::arg("self"), bp::arg("clone")), "Copy constructor"))
76
77 .add_property(
78 "linear",
79 bp::make_function(
80 &ForcePythonVisitor::getLinear, bp::with_custodian_and_ward_postcall<0, 1>()),
81 &ForcePythonVisitor::setLinear,
82 "Linear part of a *this, corresponding to the linear velocity in case of a Spatial "
83 "velocity.")
84 .add_property(
85 "angular",
86 bp::make_function(
87 &ForcePythonVisitor::getAngular, bp::with_custodian_and_ward_postcall<0, 1>()),
88 &ForcePythonVisitor::setAngular,
89 "Angular part of a *this, corresponding to the angular velocity in case of a Spatial "
90 "velocity.")
91 .add_property(
92 "vector",
93 bp::make_function(
94 (typename Force::ToVectorReturnType (Force::*)())&Force::toVector,
95 bp::return_internal_reference<>()),
96 &ForcePythonVisitor::setVector, "Returns the components of *this as a 6d vector.")
97 .add_property(
98 "np", bp::make_function(
99 (typename Force::ToVectorReturnType (Force::*)())&Force::toVector,
100 bp::return_internal_reference<>()))
101
102 .def(
103 "se3Action", &Force::template se3Action<Scalar, Options>, bp::args("self", "M"),
104 "Returns the result of the dual action of M on *this.")
105 .def(
106 "se3ActionInverse", &Force::template se3ActionInverse<Scalar, Options>,
107 bp::args("self", "M"),
108 "Returns the result of the dual action of the inverse of M on *this.")
109
110 .def(
111 "setZero", &ForcePythonVisitor::setZero, bp::arg("self"),
112 "Set the linear and angular components of *this to zero.")
113 .def(
114 "setRandom", &ForcePythonVisitor::setRandom, bp::arg("self"),
115 "Set the linear and angular components of *this to random values.")
116
117 .def(
118 "dot", (Scalar (Force::*)(const MotionDense<context::Motion> &) const) & Force::dot,
119 bp::args("self", "m"), "Dot product between *this and a Motion m.")
120
121 .def(bp::self + bp::self)
122 .def(bp::self += bp::self)
123 .def(bp::self - bp::self)
124 .def(bp::self -= bp::self)
125 .def(-bp::self)
126
127#ifndef PINOCCHIO_PYTHON_SKIP_COMPARISON_OPERATIONS
128 .def(bp::self == bp::self)
129 .def(bp::self != bp::self)
130#endif
131
132 .def(bp::self * Scalar())
133 .def(Scalar() * bp::self)
134 .def(bp::self / Scalar())
135
136#ifndef PINOCCHIO_PYTHON_SKIP_COMPARISON_OPERATIONS
137 .def(
138 "isApprox", &call<Force>::isApprox,
139 (bp::arg("self"), bp::arg("other"), bp::arg("prec") = dummy_precision),
140 "Returns true if *this is approximately equal to other, within the precision given by "
141 "prec.")
142
143 .def(
144 "isZero", &call<Force>::isZero, (bp::arg("self"), bp::arg("prec") = dummy_precision),
145 "Returns true if *this is approximately equal to the zero Force, within the precision "
146 "given by prec.")
147#endif
148
149 .def("Random", &Force::Random, "Returns a random Force.")
150 .staticmethod("Random")
151 .def("Zero", &Force::Zero, "Returns a zero Force.")
152 .staticmethod("Zero")
153
154 .def(
155 "__array__", bp::make_function(
156 (typename Force::ToVectorReturnType (Force::*)())&Force::toVector,
157 bp::return_internal_reference<>()))
158 .def(
159 "__array__", &__array__,
160 (bp::arg("self"), bp::arg("dtype") = bp::object(), bp::arg("copy") = bp::object()),
161 bp::return_internal_reference<>())
162#ifndef PINOCCHIO_PYTHON_NO_SERIALIZATION
163 .def_pickle(Pickle())
164#endif
165 ;
166 PINOCCHIO_COMPILER_DIAGNOSTIC_POP
167 }
168
169 static void expose()
170 {
171 typedef pinocchio::ForceBase<Force> ForceBase;
172 bp::objects::register_dynamic_id<ForceBase>();
173 bp::objects::register_conversion<Force, ForceBase>(false);
174
175 typedef pinocchio::ForceDense<Force> ForceDense;
176 bp::objects::register_dynamic_id<ForceBase>();
177 bp::objects::register_conversion<Force, ForceDense>(false);
178
179 typedef ::boost::python::detail::not_specified HolderType;
180 bp::class_<Force, HolderType>(
181 "Force",
182 "Force vectors, in se3* == F^6.\n\n"
183 "Supported operations ...",
184 bp::no_init)
186 .def(CastVisitor<Force>())
188 .def(::eigenpy::CopyableVisitor<Force>())
190 }
191
192 private:
193 static typename Force::ToVectorConstReturnType
194 __array__(const Force & self, bp::object, bp::object)
195 {
196 return self.toVector();
197 }
198
199 struct Pickle : bp::pickle_suite
200 {
201 static boost::python::tuple getinitargs(const Force & f)
202 {
203 return bp::make_tuple((Vector3)f.linear(), (Vector3)f.angular());
204 }
205
206 static bool getstate_manages_dict()
207 {
208 return true;
209 }
210 };
211
212 static RefVector3 getLinear(Force & self)
213 {
214 return self.linear();
215 }
216 static void setLinear(Force & self, const Vector3 & f)
217 {
218 self.linear(f);
219 }
220 static RefVector3 getAngular(Force & self)
221 {
222 return self.angular();
223 }
224 static void setAngular(Force & self, const Vector3 & n)
225 {
226 self.angular(n);
227 }
228
229 static void setZero(Force & self)
230 {
231 self.setZero();
232 }
233 static void setRandom(Force & self)
234 {
235 self.setRandom();
236 }
237
238 static void setVector(Force & self, const Vector6 & f)
239 {
240 self = f;
241 }
242 };
243
244 } // namespace python
245} // namespace pinocchio
Main pinocchio namespace.
Definition treeview.dox:11
Add the Python method cast.
Definition cast.hpp:23
Set the Python method str and repr to use the overloading operator<<.
Definition printable.hpp:21