|
| 1 | +// |
| 2 | +// Copyright (c) 2025 INRIA |
| 3 | +// |
| 4 | + |
| 5 | +#ifndef __pinocchio_spatial_se3_expr_base_hpp__ |
| 6 | +#define __pinocchio_spatial_se3_expr_base_hpp__ |
| 7 | + |
| 8 | +namespace pinocchio |
| 9 | +{ |
| 10 | + |
| 11 | +// Forward traits typedef |
| 12 | +#define PINOCCHIO_SE3_EXPR_TYPEDEF_TPL(Derived) \ |
| 13 | + typedef typename traits<Derived>::Scalar Scalar; \ |
| 14 | + typedef typename traits<Derived>::AngularType AngularType; \ |
| 15 | + typedef typename traits<Derived>::LinearType LinearType; \ |
| 16 | + typedef typename traits<Derived>::AngularRef AngularRef; \ |
| 17 | + typedef typename traits<Derived>::LinearRef LinearRef; \ |
| 18 | + typedef typename traits<Derived>::ConstAngularRef ConstAngularRef; \ |
| 19 | + typedef typename traits<Derived>::ConstLinearRef ConstLinearRef; \ |
| 20 | + typedef typename traits<Derived>::PlainType PlainType; \ |
| 21 | + enum \ |
| 22 | + { \ |
| 23 | + Options = traits<Derived>::Options, \ |
| 24 | + } |
| 25 | + |
| 26 | + // Use Eigen3 expression to optimize SE3 operations. |
| 27 | + template<typename Derived> |
| 28 | + struct SE3ExprBase |
| 29 | + { |
| 30 | + PINOCCHIO_SE3_EXPR_TYPEDEF_TPL(Derived); |
| 31 | + |
| 32 | + Derived & derived() |
| 33 | + { |
| 34 | + return *static_cast<Derived *>(this); |
| 35 | + } |
| 36 | + const Derived & derived() const |
| 37 | + { |
| 38 | + return *static_cast<const Derived *>(this); |
| 39 | + } |
| 40 | + |
| 41 | + ConstAngularRef rotation() const |
| 42 | + { |
| 43 | + return derived().rotation_impl(); |
| 44 | + } |
| 45 | + ConstLinearRef translation() const |
| 46 | + { |
| 47 | + return derived().translation_impl(); |
| 48 | + } |
| 49 | + AngularRef rotation() |
| 50 | + { |
| 51 | + return derived().rotation_impl(); |
| 52 | + } |
| 53 | + LinearRef translation() |
| 54 | + { |
| 55 | + return derived().translation_impl(); |
| 56 | + } |
| 57 | + |
| 58 | + template<typename OtherDerived> |
| 59 | + auto operator*(const SE3ExprBase<OtherDerived> & other) const |
| 60 | + { |
| 61 | + return make_se3_expr_product( |
| 62 | + rotation() * other.rotation(), translation() + rotation() * other.translation()); |
| 63 | + } |
| 64 | + |
| 65 | + template<typename OtherDerived> |
| 66 | + Derived & operator=(const SE3ExprBase<OtherDerived> & other) |
| 67 | + { |
| 68 | + rotation() = other.rotation(); |
| 69 | + translation() = other.translation(); |
| 70 | + return derived(); |
| 71 | + } |
| 72 | + |
| 73 | + SE3ExprNoalias<Derived> noalias() |
| 74 | + { |
| 75 | + return SE3ExprNoalias<Derived>(derived()); |
| 76 | + } |
| 77 | + }; |
| 78 | + |
| 79 | + // SE3Noalias use noalias in operator= |
| 80 | + template<typename Derived> |
| 81 | + struct SE3ExprNoalias |
| 82 | + { |
| 83 | + SE3ExprNoalias(Derived & expr) |
| 84 | + : expr(expr) |
| 85 | + { |
| 86 | + } |
| 87 | + |
| 88 | + template<typename OtherDerived> |
| 89 | + Derived & operator=(const SE3ExprBase<OtherDerived> & other) |
| 90 | + { |
| 91 | + expr.rotation().noalias() = other.rotation(); |
| 92 | + expr.translation().noalias() = other.translation(); |
| 93 | + return expr; |
| 94 | + } |
| 95 | + |
| 96 | + Derived & expr; |
| 97 | + }; |
| 98 | + |
| 99 | + template<typename RotProduct, typename TransProduct> |
| 100 | + struct traits<SE3ExprProduct<RotProduct, TransProduct>> |
| 101 | + { |
| 102 | + enum |
| 103 | + { |
| 104 | + Options = 0 |
| 105 | + }; |
| 106 | + typedef double Scalar; |
| 107 | + typedef RotProduct AngularType; |
| 108 | + typedef RotProduct & AngularRef; |
| 109 | + typedef const RotProduct & ConstAngularRef; |
| 110 | + typedef TransProduct LinearType; |
| 111 | + typedef TransProduct & LinearRef; |
| 112 | + typedef const TransProduct & ConstLinearRef; |
| 113 | + typedef SE3ExprProduct<RotProduct, TransProduct> PlainType; |
| 114 | + }; |
| 115 | + |
| 116 | + template<typename RotProduct, typename TransProduct> |
| 117 | + struct SE3ExprProduct : SE3ExprBase<SE3ExprProduct<RotProduct, TransProduct>> |
| 118 | + { |
| 119 | + PINOCCHIO_SE3_EXPR_TYPEDEF_TPL(SE3ExprProduct); |
| 120 | + |
| 121 | + SE3ExprProduct(RotProduct rot_prod, TransProduct trans_prod) |
| 122 | + : rot_prod(rot_prod) |
| 123 | + , trans_prod(trans_prod) |
| 124 | + { |
| 125 | + } |
| 126 | + |
| 127 | + ConstAngularRef rotation_impl() const |
| 128 | + { |
| 129 | + return rot_prod; |
| 130 | + } |
| 131 | + ConstLinearRef translation_impl() const |
| 132 | + { |
| 133 | + return trans_prod; |
| 134 | + } |
| 135 | + AngularRef rotation_impl() |
| 136 | + { |
| 137 | + return rot_prod; |
| 138 | + } |
| 139 | + LinearRef translation_impl() |
| 140 | + { |
| 141 | + return trans_prod; |
| 142 | + } |
| 143 | + |
| 144 | + RotProduct rot_prod; |
| 145 | + TransProduct trans_prod; |
| 146 | + }; |
| 147 | + |
| 148 | + template<typename RotProduct, typename TransProduct> |
| 149 | + inline SE3ExprProduct<RotProduct, TransProduct> |
| 150 | + make_se3_expr_product(RotProduct rot_prod, TransProduct trans_prod) |
| 151 | + { |
| 152 | + return SE3ExprProduct<RotProduct, TransProduct>(rot_prod, trans_prod); |
| 153 | + } |
| 154 | +} // namespace pinocchio |
| 155 | + |
| 156 | +#endif // __pinocchio_spatial_se3_expr_base_hpp__ |
0 commit comments