GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: include/pinocchio/bindings/python/spatial/motion.hpp Lines: 44 60 73.3 %
Date: 2024-04-26 13:14:21 Branches: 67 150 44.7 %

Line Branch Exec Source
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_motion_hpp__
7
#define __pinocchio_python_spatial_motion_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/motion.hpp"
15
#include "pinocchio/spatial/force.hpp"
16
#include "pinocchio/bindings/python/fwd.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::Motion)
22
#endif
23
24
namespace pinocchio
25
{
26
  namespace python
27
  {
28
    namespace bp = boost::python;
29
30
    template<typename T> struct call;
31
32
    template<typename Scalar, int Options>
33
    struct call< MotionTpl<Scalar,Options> >
34
    {
35
      typedef MotionTpl<Scalar,Options> Motion;
36
37
      static bool isApprox(const Motion & self, const Motion & other,
38
                           const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
39
      {
40
        return self.isApprox(other,prec);
41
      }
42
43
      static bool isZero(const Motion & self,
44
                         const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
45
      {
46
        return self.isZero(prec);
47
      }
48
    };
49
50
38
    BOOST_PYTHON_FUNCTION_OVERLOADS(isApproxMotion_overload,call<Motion>::isApprox,2,3)
51
    BOOST_PYTHON_FUNCTION_OVERLOADS(isZero_overload,call<Motion>::isZero,1,2)
52
53
    template<typename Motion>
54
    struct MotionPythonVisitor
55
      : public boost::python::def_visitor< MotionPythonVisitor<Motion> >
56
    {
57
      enum { Options = traits<Motion>::Options };
58
59
      typedef typename Motion::Scalar Scalar;
60
      typedef ForceTpl<Scalar,traits<Motion>::Options> Force;
61
      typedef typename Motion::Vector6 Vector6;
62
      typedef typename Motion::Vector3 Vector3;
63
64
      typedef typename Eigen::Map<Vector3> MapVector3;
65
      typedef typename Eigen::Ref<Vector3> RefVector3;
66
67
    public:
68
69
      template<class PyClass>
70
19
      void visit(PyClass& cl) const
71
      {
72
        cl
73
        .def(bp::init<>(bp::arg("self"),"Default constructor"))
74

19
        .def(bp::init<Vector3,Vector3>
75
             (bp::args("self","linear","angular"),
76
              "Initialize from linear and angular components of a Motion vector (don't mix the order)."))
77

38
        .def(bp::init<Vector6>((bp::arg("self"),bp::arg("array")),"Init from a vector 6 [linear velocity, angular velocity]"))
78


38
        .def(bp::init<Motion>((bp::arg("self"),bp::arg("other")),"Copy constructor."))
79
80


38
        .add_property("linear",
81
                      bp::make_function(&MotionPythonVisitor::getLinear,
82
                                        bp::with_custodian_and_ward_postcall<0,1>()),
83
                      &MotionPythonVisitor::setLinear,
84
                      "Linear part of a *this, corresponding to the linear velocity in case of a Spatial velocity.")
85

38
        .add_property("angular",
86
                      bp::make_function(&MotionPythonVisitor::getAngular,
87
                                        bp::with_custodian_and_ward_postcall<0,1>()),
88
                      &MotionPythonVisitor::setAngular,
89
                      "Angular part of a *this, corresponding to the angular velocity in case of a Spatial velocity.")
90

38
        .add_property("vector",
91
                      bp::make_function((typename Motion::ToVectorReturnType (Motion::*)())&Motion::toVector,
92
                                         bp::return_internal_reference<>()),
93
                      &MotionPythonVisitor::setVector,
94
                      "Returns the components of *this as a 6d vector.")
95

38
        .add_property("np",
96
                      bp::make_function((typename Motion::ToVectorReturnType (Motion::*)())&Motion::toVector,
97
                                         bp::return_internal_reference<>()))
98
99

38
        .def("se3Action",&Motion::template se3Action<Scalar,Options>,
100
             bp::args("self","M"),"Returns the result of the action of M on *this.")
101
38
        .def("se3ActionInverse",&Motion::template se3ActionInverse<Scalar,Options>,
102
             bp::args("self","M"),"Returns the result of the action of the inverse of M on *this.")
103
104

38
        .add_property("action",&Motion::toActionMatrix,"Returns the action matrix of *this (acting on Motion).")
105
19
        .add_property("dualAction",&Motion::toDualActionMatrix,"Returns the dual action matrix of *this (acting on Force).")
106
19
        .add_property("homogeneous", &Motion::toHomogeneousMatrix, "Equivalent homogeneous representation of the Motion vector")
107
108
19
        .def("setZero",&MotionPythonVisitor::setZero,bp::arg("self"),
109
             "Set the linear and angular components of *this to zero.")
110

38
        .def("setRandom",&MotionPythonVisitor::setRandom,bp::arg("self"),
111
             "Set the linear and angular components of *this to random values.")
112
113

38
        .def("cross",(Motion (Motion::*)(const Motion &) const) &Motion::cross,
114
             bp::args("self","m"),"Action of *this onto another Motion m. Returns ยจ*this x m.")
115
38
        .def("cross",(Force (Motion::*)(const Force &) const) &Motion::cross,
116
             bp::args("self","f"),"Dual action of *this onto a Force f. Returns *this x* f.")
117
118

57
        .def(bp::self + bp::self)
119

38
        .def(bp::self += bp::self)
120
19
        .def(bp::self - bp::self)
121
19
        .def(bp::self -= bp::self)
122
19
        .def(-bp::self)
123
19
        .def(bp::self ^ bp::self)
124

19
        .def(bp::self ^ Force())
125
126
19
        .def(bp::self == bp::self)
127
19
        .def(bp::self != bp::self)
128
129
19
        .def(bp::self * Scalar())
130
19
        .def(Scalar() * bp::self)
131
19
        .def(bp::self / Scalar())
132
133
19
        .def("isApprox",
134
             call<Motion>::isApprox,
135
             isApproxMotion_overload(bp::args("self","other","prec"),
136
                                     "Returns true if *this is approximately equal to other, within the precision given by prec."))
137
138

38
        .def("isZero",
139
             call<Motion>::isZero,
140
             isZero_overload(bp::args("self","prec"),
141
                             "Returns true if *this is approximately equal to the zero Motion, within the precision given by prec."))
142
143

38
        .def("Random",&Motion::Random,"Returns a random Motion.")
144
19
        .staticmethod("Random")
145
19
        .def("Zero",&Motion::Zero,"Returns a zero Motion.")
146
19
        .staticmethod("Zero")
147
148
19
        .def("__array__",bp::make_function((typename Motion::ToVectorReturnType (Motion::*)())&Motion::toVector,
149
                                            bp::return_internal_reference<>()))
150
151

19
        .def_pickle(Pickle())
152
        ;
153
19
      }
154
155
19
      static void expose()
156
      {
157
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 6 && EIGENPY_VERSION_AT_LEAST(2,9,0)
158
    typedef PINOCCHIO_SHARED_PTR_HOLDER_TYPE(Motion) HolderType;
159
#else
160
    typedef ::boost::python::detail::not_specified HolderType;
161
#endif
162
        bp::class_<Motion,HolderType>("Motion",
163
                           "Motion vectors, in se3 == M^6.\n\n"
164
                           "Supported operations ...",
165
                           bp::no_init)
166
        .def(MotionPythonVisitor<Motion>())
167
19
        .def(CopyableVisitor<Motion>())
168

19
        .def(PrintableVisitor<Motion>())
169
        ;
170
19
      }
171
172
    private:
173
174
      struct Pickle : bp::pickle_suite
175
      {
176
        static
177
        boost::python::tuple
178
        getinitargs(const Motion & m)
179
        { return bp::make_tuple((Vector3)m.linear(),(Vector3)m.angular()); }
180
181
19
        static bool getstate_manages_dict() { return true; }
182
      };
183
184
      static RefVector3 getLinear(Motion & self) { return self.linear(); }
185
      static void setLinear (Motion & self, const Vector3 & v) { self.linear(v); }
186
      static RefVector3 getAngular(Motion & self) { return self.angular(); }
187
      static void setAngular(Motion & self, const Vector3 & w) { self.angular(w); }
188
189
      static void setVector(Motion & self, const Vector6 & v) { self = v; }
190
191
      static void setZero(Motion & self) { self.setZero(); }
192
      static void setRandom(Motion & self) { self.setRandom(); }
193
194
    };
195
196
  }} // namespace pinocchio::python
197
198
#endif // ifndef __pinocchio_python_spatial_motion_hpp__