| Directory: | ./ |
|---|---|
| File: | include/pinocchio/bindings/python/spatial/force.hpp |
| Date: | 2025-02-12 21:03:38 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 82 | 88 | 93.2% |
| Branches: | 90 | 187 | 48.1% |
| 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 | |||
| 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 | { | ||
| 36 | typedef ForceTpl<Scalar, Options> Force; | ||
| 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 | 69 | void visit(PyClass & cl) const | |
| 70 | { | ||
| 71 |
3/8✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
4 | static const Scalar dummy_precision = Eigen::NumTraits<Scalar>::dummy_precision(); |
| 72 | PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH | ||
| 73 | PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_SELF_ASSIGN_OVERLOADED | ||
| 74 |
2/4✓ Branch 2 taken 69 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 69 times.
✗ Branch 6 not taken.
|
69 | cl.def(bp::init<>(bp::arg("self"), "Default constructor")) |
| 75 |
4/8✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 69 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 69 times.
✗ Branch 11 not taken.
|
138 | .def(bp::init<const Vector3 &, const Vector3 &>( |
| 76 |
3/6✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 69 times.
✗ Branch 8 not taken.
|
207 | (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 |
3/6✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 69 times.
✗ Branch 8 not taken.
|
138 | .def(bp::init<const Vector6 &>( |
| 80 | (bp::args("self", "array")), "Init from a vector 6 [force,torque]")) | ||
| 81 |
5/10✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 69 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 69 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 69 times.
✗ Branch 14 not taken.
|
138 | .def(bp::init<const Force &>((bp::arg("self"), bp::arg("clone")), "Copy constructor")) |
| 82 | |||
| 83 |
2/4✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
|
69 | .add_property( |
| 84 | "linear", | ||
| 85 | bp::make_function( | ||
| 86 | 69 | &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 |
2/4✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
|
69 | .add_property( |
| 91 | "angular", | ||
| 92 | bp::make_function( | ||
| 93 | 69 | &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 |
2/4✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
|
69 | .add_property( |
| 98 | "vector", | ||
| 99 | bp::make_function( | ||
| 100 | (typename Force::ToVectorReturnType(Force::*)()) & Force::toVector, | ||
| 101 | 69 | bp::return_internal_reference<>()), | |
| 102 | &ForcePythonVisitor::setVector, "Returns the components of *this as a 6d vector.") | ||
| 103 |
2/4✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
|
69 | .add_property( |
| 104 | "np", bp::make_function( | ||
| 105 | (typename Force::ToVectorReturnType(Force::*)()) & Force::toVector, | ||
| 106 | 69 | bp::return_internal_reference<>())) | |
| 107 | |||
| 108 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
138 | .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 |
2/4✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
|
138 | .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 |
2/4✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
|
138 | .def( |
| 117 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
138 | "setZero", &ForcePythonVisitor::setZero, bp::arg("self"), |
| 118 | "Set the linear and angular components of *this to zero.") | ||
| 119 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
69 | .def( |
| 120 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
138 | "setRandom", &ForcePythonVisitor::setRandom, bp::arg("self"), |
| 121 | "Set the linear and angular components of *this to random values.") | ||
| 122 | |||
| 123 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
138 | .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 |
2/4✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 69 times.
✗ Branch 6 not taken.
|
69 | .def(bp::self + bp::self) |
| 128 |
1/2✓ Branch 2 taken 69 times.
✗ Branch 3 not taken.
|
69 | .def(bp::self += bp::self) |
| 129 |
1/2✓ Branch 2 taken 69 times.
✗ Branch 3 not taken.
|
69 | .def(bp::self - bp::self) |
| 130 |
1/2✓ Branch 2 taken 69 times.
✗ Branch 3 not taken.
|
69 | .def(bp::self -= bp::self) |
| 131 |
1/2✓ Branch 2 taken 69 times.
✗ Branch 3 not taken.
|
69 | .def(-bp::self) |
| 132 | |||
| 133 | #ifndef PINOCCHIO_PYTHON_SKIP_COMPARISON_OPERATIONS | ||
| 134 |
1/2✓ Branch 2 taken 65 times.
✗ Branch 3 not taken.
|
65 | .def(bp::self == bp::self) |
| 135 |
1/2✓ Branch 2 taken 65 times.
✗ Branch 3 not taken.
|
65 | .def(bp::self != bp::self) |
| 136 | #endif | ||
| 137 | |||
| 138 |
3/5✓ Branch 1 taken 4 times.
✓ Branch 2 taken 65 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
73 | .def(bp::self * Scalar()) |
| 139 |
3/5✓ Branch 1 taken 4 times.
✓ Branch 2 taken 65 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
73 | .def(Scalar() * bp::self) |
| 140 |
3/5✓ Branch 1 taken 4 times.
✓ Branch 2 taken 65 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
73 | .def(bp::self / Scalar()) |
| 141 | |||
| 142 | #ifndef PINOCCHIO_PYTHON_SKIP_COMPARISON_OPERATIONS | ||
| 143 |
2/4✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 65 times.
✗ Branch 5 not taken.
|
130 | .def( |
| 144 | "isApprox", &call<Force>::isApprox, | ||
| 145 |
5/10✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 65 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 65 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 65 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 65 times.
✗ Branch 14 not taken.
|
195 | (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 |
1/2✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
|
65 | .def( |
| 150 |
4/8✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 65 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 65 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 65 times.
✗ Branch 11 not taken.
|
130 | "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 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
69 | .def("Random", &Force::Random, "Returns a random Force.") |
| 156 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
69 | .staticmethod("Random") |
| 157 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
69 | .def("Zero", &Force::Zero, "Returns a zero Force.") |
| 158 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
69 | .staticmethod("Zero") |
| 159 | |||
| 160 |
2/4✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
|
69 | .def( |
| 161 | "__array__", bp::make_function( | ||
| 162 | (typename Force::ToVectorReturnType(Force::*)()) & Force::toVector, | ||
| 163 | 69 | bp::return_internal_reference<>())) | |
| 164 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
69 | .def( |
| 165 | "__array__", &__array__, | ||
| 166 |
9/18✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 69 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 69 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 69 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 69 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 69 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 69 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 69 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 69 times.
✗ Branch 26 not taken.
|
138 | (bp::arg("self"), bp::arg("dtype") = bp::object(), bp::arg("copy") = bp::object()), |
| 167 | 69 | bp::return_internal_reference<>()) | |
| 168 | #ifndef PINOCCHIO_PYTHON_NO_SERIALIZATION | ||
| 169 |
1/2✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
|
65 | .def_pickle(Pickle()) |
| 170 | #endif | ||
| 171 | ; | ||
| 172 | PINOCCHIO_COMPILER_DIAGNOSTIC_POP | ||
| 173 | 69 | } | |
| 174 | |||
| 175 | 69 | static void expose() | |
| 176 | { | ||
| 177 | typedef pinocchio::ForceBase<Force> ForceBase; | ||
| 178 | 69 | bp::objects::register_dynamic_id<ForceBase>(); | |
| 179 | 69 | bp::objects::register_conversion<Force, ForceBase>(false); | |
| 180 | |||
| 181 | typedef pinocchio::ForceDense<Force> ForceDense; | ||
| 182 | 69 | bp::objects::register_dynamic_id<ForceBase>(); | |
| 183 | 69 | 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 | 69 | bp::class_<Force, HolderType>( | |
| 191 | "Force", | ||
| 192 | "Force vectors, in se3* == F^6.\n\n" | ||
| 193 | "Supported operations ...", | ||
| 194 | bp::no_init) | ||
| 195 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
69 | .def(ForcePythonVisitor<Force>()) |
| 196 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
69 | .def(CastVisitor<Force>()) |
| 197 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
69 | .def(ExposeConstructorByCastVisitor<Force, ::pinocchio::Force>()) |
| 198 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
69 | .def(CopyableVisitor<Force>()) |
| 199 |
1/2✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
|
69 | .def(PrintableVisitor<Force>()); |
| 200 | 69 | } | |
| 201 | |||
| 202 | private: | ||
| 203 | static typename Force::ToVectorConstReturnType | ||
| 204 | 1 | __array__(const Force & self, bp::object, bp::object) | |
| 205 | { | ||
| 206 | 1 | 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 | 65 | static bool getstate_manages_dict() | |
| 217 | { | ||
| 218 | 65 | return true; | |
| 219 | } | ||
| 220 | }; | ||
| 221 | |||
| 222 | 7 | static RefVector3 getLinear(Force & self) | |
| 223 | { | ||
| 224 |
1/2✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
|
14 | return self.linear(); |
| 225 | } | ||
| 226 | 1 | static void setLinear(Force & self, const Vector3 & f) | |
| 227 | { | ||
| 228 | 1 | self.linear(f); | |
| 229 | 1 | } | |
| 230 | 7 | static RefVector3 getAngular(Force & self) | |
| 231 | { | ||
| 232 |
1/2✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
|
14 | return self.angular(); |
| 233 | } | ||
| 234 | 1 | static void setAngular(Force & self, const Vector3 & n) | |
| 235 | { | ||
| 236 | 1 | self.angular(n); | |
| 237 | 1 | } | |
| 238 | |||
| 239 | 5 | static void setZero(Force & self) | |
| 240 | { | ||
| 241 | 5 | self.setZero(); | |
| 242 | 5 | } | |
| 243 | 2 | static void setRandom(Force & self) | |
| 244 | { | ||
| 245 | 2 | self.setRandom(); | |
| 246 | 2 | } | |
| 247 | |||
| 248 | 1 | static void setVector(Force & self, const Vector6 & f) | |
| 249 | { | ||
| 250 | 1 | self = f; | |
| 251 | 1 | } | |
| 252 | }; | ||
| 253 | |||
| 254 | } // namespace python | ||
| 255 | } // namespace pinocchio | ||
| 256 | |||
| 257 | #endif // ifndef __pinocchio_python_spatial_force_hpp__ | ||
| 258 |