GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: include/pinocchio/bindings/python/spatial/force.hpp Lines: 38 53 71.7 %
Date: 2024-04-26 13:14:21 Branches: 53 122 43.4 %

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

19
        .def(bp::init<Vector3,Vector3>
71
             (bp::args("self","linear","angular"),
72
              "Initialize from linear and angular components of a Wrench vector (don't mix the order)."))
73

38
        .def(bp::init<Vector6>((bp::args("self","array")),"Init from a vector 6 [force,torque]"))
74

38
        .def(bp::init<Force>((bp::args("self","other")),"Copy constructor."))
75
76

38
        .add_property("linear",
77
                      bp::make_function(&ForcePythonVisitor::getLinear,
78
                                        bp::with_custodian_and_ward_postcall<0,1>()),
79
                      &ForcePythonVisitor::setLinear,
80
                      "Linear part of a *this, corresponding to the linear velocity in case of a Spatial velocity.")
81

38
        .add_property("angular",
82
                      bp::make_function(&ForcePythonVisitor::getAngular,
83
                                        bp::with_custodian_and_ward_postcall<0,1>()),
84
                      &ForcePythonVisitor::setAngular,
85
                      "Angular part of a *this, corresponding to the angular velocity in case of a Spatial velocity.")
86

38
        .add_property("vector",
87
                      bp::make_function((typename Force::ToVectorReturnType (Force::*)())&Force::toVector,
88
                                        bp::return_internal_reference<>()),
89
                      &ForcePythonVisitor::setVector,
90
                      "Returns the components of *this as a 6d vector.")
91

38
        .add_property("np",
92
                      bp::make_function((typename Force::ToVectorReturnType (Force::*)())&Force::toVector,
93
                                        bp::return_internal_reference<>()))
94
95

38
        .def("se3Action",&Force::template se3Action<Scalar,Options>,
96
             bp::args("self","M"),"Returns the result of the dual action of M on *this.")
97
38
        .def("se3ActionInverse",&Force::template se3ActionInverse<Scalar,Options>,
98
             bp::args("self","M"),"Returns the result of the dual action of the inverse of M on *this.")
99
100

38
        .def("setZero",&ForcePythonVisitor::setZero,bp::arg("self"),
101
             "Set the linear and angular components of *this to zero.")
102

38
        .def("setRandom",&ForcePythonVisitor::setRandom,bp::arg("self"),
103
             "Set the linear and angular components of *this to random values.")
104
105

38
        .def(bp::self + bp::self)
106
19
        .def(bp::self += bp::self)
107
19
        .def(bp::self - bp::self)
108
19
        .def(bp::self -= bp::self)
109
19
        .def(-bp::self)
110
111
19
        .def(bp::self == bp::self)
112
19
        .def(bp::self != bp::self)
113
114
19
        .def(bp::self * Scalar())
115
19
        .def(Scalar() * bp::self)
116
19
        .def(bp::self / Scalar())
117
118
19
        .def("isApprox",
119
             &call<Force>::isApprox,
120
             isApproxForce_overload(bp::args("self","other","prec"),
121
                                     "Returns true if *this is approximately equal to other, within the precision given by prec."))
122
123

38
        .def("isZero",
124
             &call<Force>::isZero,
125
             isZero_overload(bp::args("self","prec"),
126
                             "Returns true if *this is approximately equal to the zero Force, within the precision given by prec."))
127
128

38
        .def("Random",&Force::Random,"Returns a random Force.")
129
19
        .staticmethod("Random")
130
19
        .def("Zero",&Force::Zero,"Returns a zero Force.")
131
19
        .staticmethod("Zero")
132
133
19
        .def("__array__",bp::make_function((typename Force::ToVectorReturnType (Force::*)())&Force::toVector,
134
                                           bp::return_internal_reference<>()))
135
136

19
        .def_pickle(Pickle())
137
        ;
138
19
      }
139
140
19
      static void expose()
141
      {
142
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 6 && EIGENPY_VERSION_AT_LEAST(2,9,0)
143
    typedef PINOCCHIO_SHARED_PTR_HOLDER_TYPE(Force) HolderType;
144
#else
145
    typedef ::boost::python::detail::not_specified HolderType;
146
#endif
147
        bp::class_<Force,HolderType>("Force",
148
                          "Force vectors, in se3* == F^6.\n\n"
149
                          "Supported operations ...",
150
                          bp::no_init)
151
        .def(ForcePythonVisitor<Force>())
152
19
        .def(CopyableVisitor<Force>())
153

19
        .def(PrintableVisitor<Force>())
154
        ;
155
156
19
      }
157
158
    private:
159
160
      struct Pickle : bp::pickle_suite
161
      {
162
        static
163
        boost::python::tuple
164
        getinitargs(const Force & f)
165
        { return bp::make_tuple((Vector3)f.linear(),(Vector3)f.angular()); }
166
167
19
        static bool getstate_manages_dict() { return true; }
168
      };
169
170
      static RefVector3 getLinear(Force & self ) { return self.linear(); }
171
      static void setLinear(Force & self, const Vector3 & f) { self.linear(f); }
172
      static RefVector3 getAngular(Force & self) { return self.angular(); }
173
      static void setAngular(Force & self, const Vector3 & n) { self.angular(n); }
174
175
      static void setZero(Force & self) { self.setZero(); }
176
      static void setRandom(Force & self) { self.setRandom(); }
177
178
      static void setVector(Force & self, const Vector6 & f) { self = f; }
179
180
    };
181
182
  } // namespace python
183
} // namespace pinocchio
184
185
#endif // ifndef __pinocchio_python_spatial_force_hpp__