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