Drake
eigen_geometry_pybind.h
Go to the documentation of this file.
1 #pragma once
2 
3 /// @file
4 /// Provides pybind11 `type_caster`s for Eigen geometric types.
5 /// N.B. This uses some of pybind's coding conventions.
6 ///
7 /// See http://pybind11.readthedocs.io/en/stable/advanced/cast/custom.html for
8 /// more details on custom type casters.
9 
10 #include <string>
11 #include <utility>
12 
13 #include <Eigen/Dense>
14 #include "pybind11/eigen.h"
15 
17 
18 namespace drake {
19 namespace pydrake {
20 namespace detail {
21 
22 // Implements a `type_caster<>` specialization used to convert types using a
23 // specific wrapping policy.
24 // @tparam Wrapper
25 // Struct which must provide `Type`, `WrappedType`, `unwrap`, and `wrap`.
26 // @tparam copy_only
27 // This may only pass between C++ and Python as copies, not references.
28 // See `eigen_wrapper_*` structs below for more details.
29 template <typename Wrapper>
31  using Type = typename Wrapper::Type;
32  using WrappedType = typename Wrapper::WrappedType;
33  using WrappedTypeCaster = py::detail::type_caster<WrappedType>;
34 
35  // Python to C++.
36  bool load(py::handle src, bool converter) {
37  WrappedTypeCaster caster;
38  if (!caster.load(src, converter)) {
39  return false;
40  }
41  value_ = Wrapper::unwrap(caster.operator WrappedType&());
42  loaded_ = true;
43  return true;
44  }
45 
46  // See `pybind11/eigen.h`, `type_caster<>` implementations.
47  // N.B. Do not use `PYBIND11_TYPE_CASTER(...)` so we can avoid casting
48  // garbage values.
49  operator Type&() {
50  DRAKE_DEMAND(loaded_);
51  return value_;
52  }
53  template <typename T> using cast_op_type =
54  py::detail::movable_cast_op_type<T>;
55  static constexpr auto name = WrappedTypeCaster::props::descriptor;
56 
57  // C++ to Python.
58  template <typename TType>
59  static py::handle cast(TType&& src, py::return_value_policy policy,
60  py::handle parent) {
61  if (policy == py::return_value_policy::reference ||
62  policy == py::return_value_policy::reference_internal) {
63  // N.B. We must declare a local `static constexpr` here to prevent
64  // linking errors. This does not appear achievable with
65  // `constexpr char[]`, so we use `py::detail::descr`.
66  // See `pybind11/pybind11.h`, `cpp_function::initialize(...)` for an
67  // example.
68  static constexpr auto original_name = Wrapper::original_name;
69  throw py::cast_error(
70  std::string("Can only pass ") + original_name.text +
71  " by value.");
72  }
73  return WrappedTypeCaster::cast(
74  Wrapper::wrap(std::forward<TType>(src)), policy, parent);
75  }
76 
77  private:
78  bool loaded_{false};
79  Type value_;
80 };
81 
82 // Wrapper for Eigen::Translation<>, to be used as first parameter to
83 // `type_caster_wrapped`.
84 // Since there are not many special operations for a translation vector, we
85 // shall return it as a nominal vector.
86 template <typename T, int Dim>
88  using Type = Eigen::Translation<T, Dim>;
89  using WrappedType = Eigen::Matrix<T, Dim, 1>;
90  static constexpr auto original_name = py::detail::_("Eigen::Translation<>");
91  static Type unwrap(const WrappedType& arg_wrapped) {
92  return Type(arg_wrapped);
93  }
94  static WrappedType wrap(const Type& arg) {
95  return arg.vector();
96  }
97 };
98 
99 // N.B. Since `Isometry3<>` and `Eigen::Quaternion<>` have more
100 // complicated structures, they are registered as types in `eigen_geometry_py`.
101 
102 } // namespace detail
103 } // namespace pydrake
104 } // namespace drake
105 
106 namespace pybind11 {
107 namespace detail {
108 
109 template <typename T, int Dim>
110 struct type_caster<Eigen::Translation<T, Dim>>
112  drake::pydrake::detail::wrapper_eigen_translation<T, Dim>> {};
113 
114 } // namespace detail
115 } // namespace pybind11
Eigen::Matrix< T, Dim, 1 > WrappedType
Definition: eigen_geometry_pybind.h:89
typename Wrapper::Type Type
Definition: eigen_geometry_pybind.h:31
Definition: automotive_demo.cc:90
bool load(py::handle src, bool converter)
Definition: eigen_geometry_pybind.h:36
Definition: eigen_geometry_pybind.h:106
static Type unwrap(const WrappedType &arg_wrapped)
Definition: eigen_geometry_pybind.h:91
Definition: autodiff_overloads.h:34
typename drake::pydrake::detail::wrapper_eigen_translation< T, Dim >::WrappedType WrappedType
Definition: eigen_geometry_pybind.h:32
Provides Drake&#39;s assertion implementation.
Definition: eigen_geometry_pybind.h:87
#define DRAKE_DEMAND(condition)
Evaluates condition and iff the value is false will trigger an assertion failure with a message showi...
Definition: drake_assert.h:45
py::detail::type_caster< WrappedType > WrappedTypeCaster
Definition: eigen_geometry_pybind.h:33
Eigen::Translation< T, Dim > Type
Definition: eigen_geometry_pybind.h:88
static constexpr auto name
Definition: eigen_geometry_pybind.h:55
py::detail::movable_cast_op_type< T > cast_op_type
Definition: eigen_geometry_pybind.h:54
static WrappedType wrap(const Type &arg)
Definition: eigen_geometry_pybind.h:94
static py::handle cast(TType &&src, py::return_value_policy policy, py::handle parent)
Definition: eigen_geometry_pybind.h:59
Definition: eigen_geometry_pybind.h:30