4#ifndef __multicontact_api_geometry_linear_cone_hpp__
5#define __multicontact_api_geometry_linear_cone_hpp__
8#include <Eigen/Geometry>
9#include <pinocchio/spatial/se3.hpp>
15#define EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_ROWS_SIZE(TYPE, ROWS) \
16 EIGEN_STATIC_ASSERT(TYPE::RowsAtCompileTime == ROWS, \
17 THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE)
22template <
typename _Scalar,
int _dim,
int _Options>
25 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
29 typedef Eigen::Matrix<Scalar, dim, dim, Options>
MatrixD;
30 typedef Eigen::Matrix<Scalar, dim, 1, Options>
VectorD;
31 typedef Eigen::DenseIndex
Index;
37 template <
typename EigenDerived>
50 template <
typename S2,
int O2>
54 m_rays.conservativeResize(Eigen::NoChange_t(),
m_rays.cols() + 1);
55 m_rays.template rightCols<1>() = ray.normalized();
58 template <
typename EigenDerived>
59 void stack(
const Eigen::MatrixBase<EigenDerived>&
rays) {
65 template <
typename S2,
int O2>
77 template <
typename S2,
int O2>
82 template <
typename S2,
int O2>
84 return !(*
this == other);
87 template <
typename S2,
int O2>
90 const Scalar& prec = Eigen::NumTraits<Scalar>::dummy_precision())
const {
94 void disp(std::ostream& os)
const { os <<
"Rays:\n" <<
m_rays << std::endl; }
109 template <
class Archive>
110 void save(Archive& ar,
const unsigned int )
const {
111 ar& boost::serialization::make_nvp(
"rays",
m_rays);
114 template <
class Archive>
115 void load(Archive& ar,
const unsigned int ) {
116 ar >> boost::serialization::make_nvp(
"rays",
m_rays);
119 BOOST_SERIALIZATION_SPLIT_MEMBER()
122template <
typename _Scalar,
int _Options>
124 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
128 typedef pinocchio::SE3Tpl<_Scalar, _Options>
SE3;
129 using typename Base::Scalar;
133 using typename Base::Index;
134 using typename Base::MatrixD;
135 using typename Base::MatrixDx;
136 using typename Base::VectorD;
137 using Base::operator==;
138 using Base::operator!=;
148 template <
typename EigenDerived>
157 const int num_rays) {
163 const Scalar theta_offset) {
164 assert(mu >= 0. &&
"mu must be positive");
165 assert(num_rays >= 1 &&
"The number of rays must be at least one");
167 const VectorD normalized_direction(direction.normalized());
170 const Scalar angle = (2. * M_PI) / num_rays;
172 const MatrixD Po(MatrixD::Identity() -
173 normalized_direction * normalized_direction.transpose());
176 AngleAxis(theta_offset, normalized_direction).toRotationMatrix());
177 const VectorD init_direction(rot_offset *
178 (Po * VectorD::Ones()).normalized());
180 AngleAxis(angle, normalized_direction).toRotationMatrix());
182 VectorD ray((direction + mu * init_direction).normalized());
184 for (
int k = 0; k < num_rays; ++k) {
185 cone.
rays().col(k) = ray;
186 if (k != num_rays - 1) ray = rot * ray;
194 typedef typename WrenchCone::MatrixDx::ColXpr Col6Xpr;
195 typedef typename MatrixDx::ConstColXpr ConstCol3Xpr;
197 const typename SE3::Matrix3& R = M.rotation();
198 const typename SE3::Vector3& t = M.translation();
201 ConstCol3Xpr in_col =
rays().col(k);
202 Col6Xpr out_col = res.
rays().col(k);
204 out_col.template head<3>() = R * in_col;
205 out_col.template tail<3>() = t.cross(out_col.template head<3>());
211 template <
typename S2,
int O2>
214 const Scalar& prec = Eigen::NumTraits<Scalar>::dummy_precision())
const {
215 return Base::isApprox(other, prec);
220 res.
rays().template topRows<3>() =
rays();
221 res.
rays().template bottomRows<3>().setZero();
226template <
typename _Scalar,
int _Options>
228 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
232 typedef pinocchio::SE3Tpl<_Scalar, _Options>
SE3;
233 using typename Base::Scalar;
237 using typename Base::Index;
238 using typename Base::MatrixDx;
239 using typename Base::VectorD;
240 using Base::operator==;
241 using Base::operator!=;
249 typedef typename Matrix6x::template NRowsBlockXpr<3>::Type
LinearBlock;
260 template <
typename EigenDerived>
268 template <
typename S2,
int O2>
271 rays().template topRows<3>() = force_cone.
rays();
272 rays().template bottomRows<3>().setZero();
276 template <
typename S2,
int O2>
281 typedef typename MatrixDx::ColXpr Col6Xpr;
282 typedef typename MatrixDx::ConstColXpr ConstCol6Xpr;
284 const typename SE3::Matrix3& R = M.rotation();
285 const typename SE3::Vector3& t = M.translation();
288 ConstCol6Xpr in_col =
rays().col(k);
289 Col6Xpr out_col = res.
rays().col(k);
291 out_col.template head<3>() = R * in_col.template head<3>();
292 out_col.template tail<3>() =
293 t.cross(out_col.template head<3>()) + R * in_col.template tail<3>();
299 template <
typename S2,
int O2>
302 const Scalar& prec = Eigen::NumTraits<Scalar>::dummy_precision())
const {
303 return Base::isApprox(other, prec);
#define EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_ROWS_SIZE(TYPE, ROWS)
Definition linear-cone.hpp:15