Skip to content

Commit fa6bb97

Browse files
author
ipuch
committed
feat/refactor(joint-ellipsoid): joint specialization
1 parent 1f1c109 commit fa6bb97

File tree

1 file changed

+274
-7
lines changed

1 file changed

+274
-7
lines changed

include/pinocchio/multibody/joint/joint-ellipsoid.hpp

Lines changed: 274 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,270 @@ namespace pinocchio
1616
template<typename Scalar, int Options>
1717
struct JointEllipsoidTpl;
1818

19+
template<typename Scalar, int Options>
20+
struct JointMotionSubspaceEllipsoidTpl;
21+
22+
template<typename Scalar, int Options>
23+
struct SE3GroupAction<JointMotionSubspaceEllipsoidTpl<Scalar, Options>>
24+
{
25+
typedef Eigen::Matrix<Scalar, 6, 3, Options> ReturnType;
26+
};
27+
28+
template<typename Scalar, int Options, typename MotionDerived>
29+
struct MotionAlgebraAction<JointMotionSubspaceEllipsoidTpl<Scalar, Options>, MotionDerived>
30+
{
31+
typedef Eigen::Matrix<Scalar, 6, 3, Options> ReturnType;
32+
};
33+
34+
template<typename Scalar, int Options, typename ForceDerived>
35+
struct ConstraintForceOp<JointMotionSubspaceEllipsoidTpl<Scalar, Options>, ForceDerived>
36+
{
37+
typedef Eigen::Matrix<Scalar, 3, 1, Options> ReturnType;
38+
};
39+
40+
template<typename Scalar, int Options, typename ForceSet>
41+
struct ConstraintForceSetOp<JointMotionSubspaceEllipsoidTpl<Scalar, Options>, ForceSet>
42+
{
43+
typedef Eigen::Matrix<Scalar, 3, Eigen::Dynamic, Options> ReturnType;
44+
};
45+
46+
template<typename _Scalar, int _Options>
47+
struct traits<JointMotionSubspaceEllipsoidTpl<_Scalar, _Options>>
48+
{
49+
typedef _Scalar Scalar;
50+
enum
51+
{
52+
Options = _Options
53+
};
54+
enum
55+
{
56+
LINEAR = 0,
57+
ANGULAR = 3
58+
};
59+
60+
typedef MotionTpl<Scalar, Options> JointMotion;
61+
typedef Eigen::Matrix<Scalar, 3, 1, Options> JointForce;
62+
typedef Eigen::Matrix<Scalar, 6, 3, Options> DenseBase;
63+
typedef Eigen::Matrix<Scalar, 3, 3, Options> ReducedSquaredMatrix;
64+
65+
typedef DenseBase MatrixReturnType;
66+
typedef const DenseBase ConstMatrixReturnType;
67+
68+
typedef typename ReducedSquaredMatrix::IdentityReturnType StDiagonalMatrixSOperationReturnType;
69+
};
70+
71+
72+
template<typename _Scalar, int _Options>
73+
struct JointMotionSubspaceEllipsoidTpl
74+
: JointMotionSubspaceBase<JointMotionSubspaceEllipsoidTpl<_Scalar, _Options>>
75+
{
76+
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
77+
78+
PINOCCHIO_CONSTRAINT_TYPEDEF_TPL(JointMotionSubspaceEllipsoidTpl)
79+
enum
80+
{
81+
NV = 3
82+
};
83+
84+
typedef Eigen::Matrix<Scalar, 6, 3, Options> Matrix63;
85+
Matrix63 S;
86+
87+
JointMotionSubspaceEllipsoidTpl()
88+
{
89+
}
90+
91+
template<typename Vector3Like>
92+
JointMotion __mult__(const Eigen::MatrixBase<Vector3Like> & v) const
93+
{
94+
// Compute first 6 rows from first 2 columns
95+
Eigen::Matrix<Scalar, 6, 1> result = S.template block<6,2>(0,0) * v.template segment<2>(0);
96+
97+
// Add contribution from last column (only row 5 is non-zero: S(5,2) = 1)
98+
result[5] += v[2];
99+
100+
return JointMotion(result);
101+
}
102+
103+
template<typename S1, int O1>
104+
typename SE3GroupAction<JointMotionSubspaceEllipsoidTpl>::ReturnType
105+
se3Action(const SE3Tpl<S1, O1> & m) const
106+
{
107+
typedef typename SE3GroupAction<JointMotionSubspaceEllipsoidTpl>::ReturnType ReturnType;
108+
ReturnType res;
109+
// Apply SE3 action to first two columns
110+
motionSet::se3Action(m, S.template leftCols<2>(), res.template leftCols<2>());
111+
112+
res.template block<3, 1>(LINEAR, 2).noalias() = m.translation().cross(m.rotation().col(2));
113+
res.template block<3, 1>(ANGULAR, 2) = m.rotation().col(2);
114+
115+
116+
return res;
117+
}
118+
119+
template<typename S1, int O1>
120+
typename SE3GroupAction<JointMotionSubspaceEllipsoidTpl>::ReturnType
121+
se3ActionInverse(const SE3Tpl<S1, O1> & m) const
122+
{
123+
typedef typename SE3GroupAction<JointMotionSubspaceEllipsoidTpl>::ReturnType ReturnType;
124+
ReturnType res;
125+
// Apply inverse SE3 action to first two columns
126+
motionSet::se3ActionInverse(m, S.template leftCols<2>(), res.template leftCols<2>());
127+
128+
// Third column: inverse action on [0, 0, 0, 0, 0, 1]^T
129+
// angular part: R^T * e_z
130+
res.template block<3, 1>(ANGULAR, 2) = m.rotation().transpose().col(2);
131+
// linear part: R^T * (t × e_z) = R^T * [-t_y, t_x, 0]^T
132+
typedef Eigen::Matrix<Scalar, 3, 1, Options> Vector3;
133+
const Vector3 t_cross_ez(-m.translation()[1], m.translation()[0], Scalar(0));
134+
res.template block<3, 1>(LINEAR, 2).noalias() = m.rotation().transpose() * t_cross_ez;
135+
136+
return res;
137+
}
138+
139+
int nv_impl() const
140+
{
141+
return NV;
142+
}
143+
144+
struct TransposeConst : JointMotionSubspaceTransposeBase<JointMotionSubspaceEllipsoidTpl>
145+
{
146+
const JointMotionSubspaceEllipsoidTpl & ref;
147+
TransposeConst(const JointMotionSubspaceEllipsoidTpl & ref)
148+
: ref(ref)
149+
{
150+
}
151+
152+
template<typename ForceDerived>
153+
typename ConstraintForceOp<JointMotionSubspaceEllipsoidTpl, ForceDerived>::ReturnType
154+
operator*(const ForceDense<ForceDerived> & f) const
155+
{
156+
typedef typename ConstraintForceOp<JointMotionSubspaceEllipsoidTpl, ForceDerived>::ReturnType ReturnType;
157+
ReturnType res;
158+
159+
// First two rows: S[:, 0:2]^T * f
160+
res.template head<2>().noalias() = ref.S.template leftCols<2>().transpose() * f.toVector();
161+
162+
// Third row: [0,0,0,0,0,1]^T · f = f.angular()[2]
163+
res[2] = f.angular()[2];
164+
165+
return res;
166+
}
167+
168+
/// [CRBA] MatrixBase operator* (Constraint::Transpose S, ForceSet::Block)
169+
template<typename Derived>
170+
Eigen::Matrix<
171+
Scalar, 3, Derived::ColsAtCompileTime,
172+
Options | Eigen::RowMajor,
173+
3, Derived::MaxColsAtCompileTime>
174+
operator*(const Eigen::MatrixBase<Derived> & F) const
175+
{
176+
EIGEN_STATIC_ASSERT(Derived::RowsAtCompileTime == 6, THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE)
177+
typedef Eigen::Matrix<
178+
Scalar, 3, Derived::ColsAtCompileTime,
179+
Options | Eigen::RowMajor,
180+
3, Derived::MaxColsAtCompileTime> ReturnType;
181+
182+
ReturnType res(3, F.cols());
183+
184+
// First two rows: S[:, 0:2]^T * F
185+
res.template topRows<2>().noalias() = ref.S.template leftCols<2>().transpose() * F.derived();
186+
187+
// Third row: [0,0,0,0,0,1]^T · F = F.row(5)
188+
res.row(2) = F.row(5);
189+
190+
return res;
191+
}
192+
}; // struct TransposeConst
193+
194+
TransposeConst transpose() const
195+
{
196+
return TransposeConst(*this);
197+
}
198+
199+
/* CRBA joint operators
200+
* - ForceSet::Block = ForceSet
201+
* - ForceSet operator* (Inertia Y,Constraint S)
202+
* - MatrixBase operator* (Constraint::Transpose S, ForceSet::Block)
203+
* - SE3::act(ForceSet::Block)
204+
*/
205+
DenseBase matrix_impl() const
206+
{
207+
DenseBase res;
208+
209+
// Columns 0-1: copy the first two columns of S (6x2)
210+
res.template leftCols<2>() = S.template leftCols<2>();
211+
212+
// Column 2: sparse [0, 0, 0, 0, 0, 1]^T
213+
res.template block<5, 1>(0, 2).setZero();
214+
res(5, 2) = Scalar(1);
215+
216+
return res;
217+
}
218+
219+
template<typename MotionDerived>
220+
typename MotionAlgebraAction<JointMotionSubspaceEllipsoidTpl, MotionDerived>::ReturnType
221+
motionAction(const MotionDense<MotionDerived> & m) const
222+
{
223+
typedef
224+
typename MotionAlgebraAction<JointMotionSubspaceEllipsoidTpl, MotionDerived>::ReturnType
225+
ReturnType;
226+
ReturnType res;
227+
228+
// Motion action on first two columns
229+
motionSet::motionAction(m, S.template leftCols<2>(), res.template leftCols<2>());
230+
231+
// Motion action on third column [0, 0, 0, 0, 0, 1]^T
232+
// [v; w] × [0; e_z] = [v × e_z; w × e_z]
233+
const typename MotionDense<MotionDerived>::ConstLinearType & v_lin = m.linear();
234+
const typename MotionDense<MotionDerived>::ConstAngularType & w = m.angular();
235+
236+
// v × e_z = [v[1], -v[0], 0]
237+
res(LINEAR + 0, 2) = v_lin[1];
238+
res(LINEAR + 1, 2) = -v_lin[0];
239+
res(LINEAR + 2, 2) = Scalar(0);
240+
241+
// w × e_z = [w[1], -w[0], 0]
242+
res(ANGULAR + 0, 2) = w[1];
243+
res(ANGULAR + 1, 2) = -w[0];
244+
res(ANGULAR + 2, 2) = Scalar(0);
245+
246+
return res;
247+
}
248+
249+
bool isEqual(const JointMotionSubspaceEllipsoidTpl & other) const
250+
{
251+
return S == other.S;
252+
}
253+
254+
}; // struct JointMotionSubspaceEllipsoidTpl
255+
256+
/* [CRBA] ForceSet operator* (Inertia Y, Constraint S) */
257+
template<typename S1, int O1, typename S2, int O2>
258+
Eigen::Matrix<S1, 6, 3, O1>
259+
operator*(const InertiaTpl<S1, O1> & Y, const JointMotionSubspaceEllipsoidTpl<S2, O2> & S)
260+
{
261+
// Y * S where Y is 6x6 inertia and S is 6x3 motion subspace
262+
// Returns 6x3 force set
263+
typedef InertiaTpl<S1, O1> Inertia;
264+
Eigen::Matrix<S1, 6, 3, O1> M;
265+
M.noalias() = Y.matrix() * S.matrix();
266+
return M;
267+
}
268+
269+
/* [ABA] Y*S operator (Matrix6 Y, Constraint S) */
270+
template<typename Matrix6Like, typename S2, int O2>
271+
typename MatrixMatrixProduct<
272+
Matrix6Like,
273+
typename JointMotionSubspaceEllipsoidTpl<S2, O2>::DenseBase>::type
274+
operator*(
275+
const Eigen::MatrixBase<Matrix6Like> & Y,
276+
const JointMotionSubspaceEllipsoidTpl<S2, O2> & S)
277+
{
278+
EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Matrix6Like, 6, 6);
279+
return Y.derived() * S.matrix();
280+
}
281+
282+
19283
template<typename _Scalar, int _Options>
20284
struct traits<JointEllipsoidTpl<_Scalar, _Options>>
21285
{
@@ -32,7 +296,9 @@ namespace pinocchio
32296
};
33297
typedef JointDataEllipsoidTpl<Scalar, Options> JointDataDerived;
34298
typedef JointModelEllipsoidTpl<Scalar, Options> JointModelDerived;
35-
typedef JointMotionSubspaceTpl<3, Scalar, Options, 3> Constraint_t;
299+
// typedef JointMotionSubspaceTpl<3, Scalar, Options, 3> Constraint_t;
300+
typedef JointMotionSubspaceEllipsoidTpl<Scalar, Options> Constraint_t;
301+
36302
typedef SE3Tpl<Scalar, Options> Transformation_t;
37303

38304
typedef MotionTpl<Scalar, Options> Motion_t;
@@ -398,12 +664,13 @@ namespace pinocchio
398664
S_32 = dndotx_dqdot1 * radius_a * s1 - dndoty_dqdot1 * radius_b * c1 * s0
399665
+ dndotz_dqdot1 * radius_c * c0 * c1;
400666

401-
data.S.matrix() << S_11 , S_12 , Scalar(0),
402-
S_21 , S_22 , Scalar(0),
403-
S_31 , S_32 , Scalar(0),
404-
c1 * c2, s2 , Scalar(0),
405-
-c1 * s2, c2 , Scalar(0),
406-
s1 , Scalar(0), Scalar(1);
667+
// Write directly to the internal matrix S, not to matrix() which returns a copy
668+
data.S.S << S_11 , S_12 , Scalar(0),
669+
S_21 , S_22 , Scalar(0),
670+
S_31 , S_32 , Scalar(0),
671+
c1 * c2, s2 , Scalar(0),
672+
-c1 * s2, c2 , Scalar(0),
673+
s1 , Scalar(0), Scalar(1);
407674
// clang-format on
408675
}
409676

0 commit comments

Comments
 (0)