GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: include/pinocchio/multibody/force-set.hpp Lines: 38 38 100.0 %
Date: 2024-04-26 13:14:21 Branches: 48 96 50.0 %

Line Branch Exec Source
1
//
2
// Copyright (c) 2015 CNRS
3
//
4
5
#ifndef __pinocchio_force_set_hpp__
6
#define __pinocchio_force_set_hpp__
7
8
#include "pinocchio/spatial/fwd.hpp"
9
#include <Eigen/Geometry>
10
11
namespace pinocchio
12
{
13
  template<typename _Scalar, int _Options>
14
  class ForceSetTpl
15
  {
16
  public:
17
    typedef _Scalar Scalar;
18
    enum { Options = _Options };
19
    typedef Eigen::Matrix<Scalar,3,1,Options> Vector3;
20
    typedef Eigen::Matrix<Scalar,3,3,Options> Matrix3;
21
    typedef Eigen::Matrix<Scalar,6,1,Options> Vector6;
22
    typedef Eigen::Matrix<Scalar,6,6,Options> Matrix6;
23
    typedef SE3Tpl<Scalar,Options> SE3;
24
25
    typedef Eigen::Matrix<Scalar,3,Eigen::Dynamic,Options> Matrix3x;
26
    typedef Eigen::Matrix<Scalar,6,Eigen::Dynamic,Options> Matrix6x;
27
28
  public:
29
    // Constructors
30

3
    ForceSetTpl(const int & ncols ) : size(ncols),m_f(3,ncols), m_n(3,ncols)
31

3
    { m_f.fill(NAN); m_n.fill(NAN); }
32
9
    ForceSetTpl(const Matrix3x & linear, const Matrix3x & angular)
33
9
      : size((int)linear.cols()),m_f(linear), m_n(angular)
34

9
    {  assert( linear.cols() == angular.cols() ); }
35
36
12
    Matrix6x matrix() const
37
    {
38

12
      Matrix6x F(6,size); F << m_f, m_n;
39
      // F.template topRows<3>() = m_f;
40
      // F.template bottomRows<3>()  = m_n;
41
12
      return F;
42
    }
43
    operator Matrix6x () const { return matrix(); }
44
45
    // Getters
46
6
    const Matrix3x & linear() const { return m_f; }
47
6
    const Matrix3x & angular() const { return m_n; }
48
49
    /// af = aXb.act(bf)
50
4
    ForceSetTpl se3Action(const SE3 & m) const
51
    {
52

4
      Matrix3x Rf (m.rotation()*linear());
53




8
      return ForceSetTpl(Rf,skew(m.translation())*Rf+m.rotation()*angular());
54
      // TODO check if nothing better than explicitely calling skew
55
    }
56
    /// bf = aXb.actInv(af)
57
    ForceSetTpl se3ActionInverse(const SE3 & m) const
58
    {
59
      return ForceSetTpl(m.rotation().transpose()*linear(),
60
		      m.rotation().transpose()*(angular() - skew(m.translation())*linear()) );
61
      // TODO check if nothing better than explicitely calling skew
62
    }
63
64
    friend std::ostream & operator << (std::ostream & os, const ForceSetTpl & phi)
65
    {
66
      os
67
	<< "F =\n" << phi.linear() << std::endl
68
	<< "Tau =\n" << phi.angular() << std::endl;
69
      return os;
70
    }
71
72
    /* --- BLOCK ------------------------------------------------------------ */
73
    struct Block
74
    {
75
      ForceSetTpl & ref;
76
      int idx,len;
77
6
      Block( ForceSetTpl & ref, const int & idx, const int & len )
78
6
	: ref(ref), idx(idx), len(len) {}
79
80
3
      Eigen::Block<ForceSetTpl::Matrix3x> linear() { return ref.m_f.block(0,idx,3,len); }
81
3
      Eigen::Block<ForceSetTpl::Matrix3x> angular() { return ref.m_n.block(0,idx,3,len); }
82
3
      Eigen::Block<const ForceSetTpl::Matrix3x> linear()  const
83
3
      { return ((const ForceSetTpl::Matrix3x &)(ref.m_f)).block(0,idx,3,len); }
84
3
      Eigen::Block<const ForceSetTpl::Matrix3x> angular() const
85
3
      { return ((const ForceSetTpl::Matrix3x &)(ref.m_n)).block(0,idx,3,len); }
86
87
1
      ForceSetTpl::Matrix6x matrix() const
88
      {
89


1
	ForceSetTpl::Matrix6x res(6,len); res << linear(),angular();
90
1
	return res;
91
      }
92
93
2
      Block& operator= (const ForceSetTpl & copy)
94
      {
95
2
	assert(copy.size == len);
96
2
	linear() = copy.linear(); //ref.m_f.block(0,idx,3,len) = copy.m_f;
97
2
	angular() = copy.angular(); //ref.m_n.block(0,idx,3,len) = copy.m_n;
98
2
	return *this;
99
      }
100
101
      Block& operator= (const ForceSetTpl::Block & copy)
102
      {
103
	assert(copy.len == len);
104
	linear() = copy.linear(); //ref.m_f.block(0,idx,3,len) = copy.ref.m_f.block(0,copy.idx,3,copy.len);
105
	angular() = copy.angular(); //ref.m_n.block(0,idx,3,len) = copy.ref.m_n.block(0,copy.idx,3,copy.len);
106
	return *this;
107
      }
108
109
      template <typename D>
110
1
      Block& operator= (const Eigen::MatrixBase<D> & m)
111
      {
112
        eigen_assert(D::RowsAtCompileTime == 6);
113
1
        assert(m.cols() == len);
114

1
        linear() = m.template topRows<3>();
115

1
        angular() = m.template bottomRows<3>();
116
1
        return *this;
117
      }
118
119
      /// af = aXb.act(bf)
120
2
      ForceSetTpl se3Action(const SE3 & m) const
121
      {
122
	// const Eigen::Block<const Matrix3x> linear = ref.linear().block(0,idx,3,len);
123
	// const Eigen::Block<const Matrix3x> angular = ref.angular().block(0,idx,3,len);
124


2
	Matrix3x Rf ((m.rotation()*linear()));
125




4
	return ForceSetTpl(Rf,skew(m.translation())*Rf+m.rotation()*angular());
126
	// TODO check if nothing better than explicitely calling skew
127
      }
128
      /// bf = aXb.actInv(af)
129
      ForceSetTpl se3ActionInverse(const SE3 & m) const
130
      {
131
	// const Eigen::Block<const Matrix3x> linear = ref.linear().block(0,idx,3,len);
132
	// const Eigen::Block<const Matrix3x> angular = ref.angular().block(0,idx,3,len);
133
	return ForceSetTpl(m.rotation().transpose()*linear(),
134
			   m.rotation().transpose()*(angular() - skew(m.translation())*linear()) );
135
	// TODO check if nothing better than explicitely calling skew
136
      }
137
138
    };
139
140
6
    Block block(const int & idx, const int & len) { return Block(*this,idx,len); }
141
142
    /* CRBA joint operators
143
     *   - ForceSet::Block = ForceSet
144
     *   - ForceSet operator* (Inertia Y,Constraint S)
145
     *   - MatrixBase operator* (Constraint::Transpose S, ForceSet::Block)
146
     *   - SE3::act(ForceSet::Block)
147
     */
148
149
150
  public: //
151
  private:
152
    int size;
153
    Matrix3x m_f,m_n;
154
  };
155
156
  typedef ForceSetTpl<double,0> ForceSet;
157
158
  template<>
159
  struct SE3GroupAction<ForceSet::Block> { typedef ForceSet ReturnType; };
160
161
162
} // namespace pinocchio
163
164
#endif // ifndef __pinocchio_force_set_hpp__
165