centroidal_control_collection
StateSpaceModel.h
Go to the documentation of this file.
1 /* Author: Masaki Murooka */
2 
3 #pragma once
4 
5 #include <Eigen/Dense>
6 #include <unsupported/Eigen/MatrixFunctions>
7 
8 namespace CCC
9 {
20 template<int StateDim, int InputDim, int OutputDim>
22 {
23 public:
25  using StateDimVector = Eigen::Matrix<double, StateDim, 1>;
26 
28  using InputDimVector = Eigen::Matrix<double, InputDim, 1>;
29 
31  using OutputDimVector = Eigen::Matrix<double, OutputDim, 1>;
32 
33 public:
34  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
35 
42  StateSpaceModel(int state_dim = StateDim, int input_dim = InputDim, int output_dim = OutputDim)
43  : state_dim_(state_dim), input_dim_(input_dim), output_dim_(output_dim)
44  {
45  // Check dimension is positive
46  if(state_dim_ <= 0)
47  {
48  throw std::runtime_error("state_dim must be positive: " + std::to_string(state_dim_) + " <= 0");
49  }
50  if(input_dim_ < 0)
51  {
52  throw std::runtime_error("input_dim must be non-negative: " + std::to_string(input_dim_) + " < 0");
53  }
54  if(output_dim_ < 0)
55  {
56  throw std::runtime_error("output_dim must be non-negative: " + std::to_string(output_dim_) + " < 0");
57  }
58 
59  // Check dimension consistency
60  if constexpr(StateDim != Eigen::Dynamic)
61  {
62  if(state_dim_ != StateDim)
63  {
64  throw std::runtime_error("state_dim is inconsistent with template parameter: " + std::to_string(state_dim_)
65  + " != " + std::to_string(StateDim));
66  }
67  }
68  if constexpr(InputDim != Eigen::Dynamic)
69  {
70  if(input_dim_ != InputDim)
71  {
72  throw std::runtime_error("input_dim is inconsistent with template parameter: " + std::to_string(input_dim_)
73  + " != " + std::to_string(InputDim));
74  }
75  }
76  if constexpr(OutputDim != Eigen::Dynamic)
77  {
78  if(output_dim_ != OutputDim)
79  {
80  throw std::runtime_error("output_dim is inconsistent with template parameter: " + std::to_string(output_dim_)
81  + " != " + std::to_string(OutputDim));
82  }
83  }
84 
85  // Initialize with zero matrix if size is fixed
86  A_.setZero(state_dim_, state_dim_);
87  B_.setZero(state_dim_, input_dim_);
88  C_.setZero(output_dim_, state_dim_);
89  D_.setZero(output_dim_, input_dim_);
90  E_.setZero(state_dim_);
91  F_.setZero(output_dim_);
92  }
93 
98  virtual ~StateSpaceModel() = default;
99 
101  int stateDim() const
102  {
103  return state_dim_;
104  }
105 
107  int inputDim() const
108  {
109  return input_dim_;
110  }
111 
113  int outputDim() const
114  {
115  return output_dim_;
116  }
117 
124  {
125  return A_ * x + B_ * u + E_;
126  }
127 
134  {
135  return Ad_ * x + Bd_ * u + Ed_;
136  }
137 
143  {
144  return C_ * x + F_;
145  }
146 
153  {
154  return C_ * x + D_ * u + F_;
155  }
156 
164  void calcDiscMatrix(double dt)
165  {
166  dt_ = dt;
167 
168  // Zero-order hold discretization
169  // See https://en.wikipedia.org/wiki/Discretization
170  if constexpr(StateDim == Eigen::Dynamic || InputDim == Eigen::Dynamic)
171  {
172  // If dimension is dynamic
173  if(E_.norm() == 0)
174  {
175  Eigen::MatrixXd ABZero(state_dim_ + input_dim_, state_dim_ + input_dim_);
176  ABZero << dt_ * A_, dt_ * B_, Eigen::MatrixXd::Zero(input_dim_, state_dim_ + input_dim_);
177  Eigen::MatrixXd ABZeroExp = ABZero.exp();
178  Ad_ = ABZeroExp.block(0, 0, state_dim_, state_dim_);
179  Bd_ = ABZeroExp.block(0, state_dim_, state_dim_, input_dim_);
180  Ed_.setZero(state_dim_);
181  }
182  else
183  {
184  // There is no proof that this is correct.
185  Eigen::MatrixXd ABEZero(state_dim_ + input_dim_ + 1, state_dim_ + input_dim_ + 1);
186  ABEZero << dt_ * A_, dt_ * B_, dt_ * E_, Eigen::MatrixXd::Zero(input_dim_ + 1, state_dim_ + input_dim_ + 1);
187  Eigen::MatrixXd ABEZeroExp = ABEZero.exp();
188  Ad_ = ABEZeroExp.block(0, 0, state_dim_, state_dim_);
189  Bd_ = ABEZeroExp.block(0, state_dim_, state_dim_, input_dim_);
190  Ed_ = ABEZeroExp.block(0, state_dim_ + input_dim_, state_dim_, 1);
191  }
192  }
193  else
194  {
195  // If dimension is fixed
196  if(E_.norm() == 0)
197  {
198  Eigen::Matrix<double, StateDim + InputDim, StateDim + InputDim> ABZero;
199  ABZero << dt_ * A_, dt_ * B_, Eigen::Matrix<double, InputDim, StateDim + InputDim>::Zero();
200  Eigen::Matrix<double, StateDim + InputDim, StateDim + InputDim> ABZeroExp = ABZero.exp();
201  Ad_ = ABZeroExp.template block<StateDim, StateDim>(0, 0);
202  Bd_ = ABZeroExp.template block<StateDim, InputDim>(0, StateDim);
203  Ed_.setZero();
204  }
205  else
206  {
207  // There is no proof that this is correct.
208  Eigen::Matrix<double, StateDim + InputDim + 1, StateDim + InputDim + 1> ABEZero;
209  ABEZero << dt_ * A_, dt_ * B_, dt_ * E_, Eigen::Matrix<double, InputDim + 1, StateDim + InputDim + 1>::Zero();
210  Eigen::Matrix<double, StateDim + InputDim + 1, StateDim + InputDim + 1> ABEZeroExp = ABEZero.exp();
211  Ad_ = ABEZeroExp.template block<StateDim, StateDim>(0, 0);
212  Bd_ = ABEZeroExp.template block<StateDim, InputDim>(0, StateDim);
213  Ed_ = ABEZeroExp.template block<StateDim, 1>(0, StateDim + InputDim);
214  }
215  }
216  }
217 
218 public:
220  const int state_dim_ = 0;
221 
223  const int input_dim_ = 0;
224 
226  const int output_dim_ = 0;
227 
229  Eigen::Matrix<double, StateDim, StateDim> A_;
230 
232  Eigen::Matrix<double, StateDim, InputDim> B_;
233 
235  Eigen::Matrix<double, OutputDim, StateDim> C_;
236 
238  Eigen::Matrix<double, OutputDim, InputDim> D_;
239 
242 
245 
247  double dt_ = 0;
248 
250  Eigen::Matrix<double, StateDim, StateDim> Ad_;
251 
253  Eigen::Matrix<double, StateDim, InputDim> Bd_;
254 
257 };
258 } // namespace CCC
CCC::StateSpaceModel::stateDim
int stateDim() const
Gets the state dimension.
Definition: StateSpaceModel.h:101
CCC::StateSpaceModel::state_dim_
const int state_dim_
State dimension.
Definition: StateSpaceModel.h:220
CCC::StateSpaceModel::outputDim
int outputDim() const
Gets the output dimension.
Definition: StateSpaceModel.h:113
CCC::StateSpaceModel::observEq
OutputDimVector observEq(const StateDimVector &x) const
Calculate the observation equation.
Definition: StateSpaceModel.h:142
CCC::StateSpaceModel::observEq
OutputDimVector observEq(const StateDimVector &x, const InputDimVector &u) const
Calculate the observation equation.
Definition: StateSpaceModel.h:152
CCC::StateSpaceModel::E_
StateDimVector E_
Offset vector of continuous state equation.
Definition: StateSpaceModel.h:241
CCC::StateSpaceModel::input_dim_
const int input_dim_
Input dimension.
Definition: StateSpaceModel.h:223
CCC::StateSpaceModel::inputDim
int inputDim() const
Gets the input dimension.
Definition: StateSpaceModel.h:107
CCC::StateSpaceModel< 3, 1, 1 >::InputDimVector
Eigen::Matrix< double, InputDim, 1 > InputDimVector
Type of input vector.
Definition: StateSpaceModel.h:28
CCC::StateSpaceModel::Ed_
StateDimVector Ed_
Offset vector of discrete state equation.
Definition: StateSpaceModel.h:256
CCC::StateSpaceModel< 3, 1, 1 >::StateDimVector
Eigen::Matrix< double, StateDim, 1 > StateDimVector
Type of state vector.
Definition: StateSpaceModel.h:25
CCC::StateSpaceModel::StateSpaceModel
EIGEN_MAKE_ALIGNED_OPERATOR_NEW StateSpaceModel(int state_dim=StateDim, int input_dim=InputDim, int output_dim=OutputDim)
Constructor.
Definition: StateSpaceModel.h:42
CCC::StateSpaceModel
State-space model.
Definition: StateSpaceModel.h:21
CCC::StateSpaceModel::D_
Eigen::Matrix< double, OutputDim, InputDim > D_
Matrix of observation equation.
Definition: StateSpaceModel.h:238
CCC::StateSpaceModel::C_
Eigen::Matrix< double, OutputDim, StateDim > C_
Matrix of observation equation.
Definition: StateSpaceModel.h:235
CCC::StateSpaceModel::A_
Eigen::Matrix< double, StateDim, StateDim > A_
Matrix of continuous state equation.
Definition: StateSpaceModel.h:229
CCC
Definition: CommonModels.h:7
CCC::StateSpaceModel::output_dim_
const int output_dim_
Output dimension.
Definition: StateSpaceModel.h:226
CCC::StateSpaceModel::Bd_
Eigen::Matrix< double, StateDim, InputDim > Bd_
Matrix of discrete state equation.
Definition: StateSpaceModel.h:253
CCC::StateSpaceModel::calcDiscMatrix
void calcDiscMatrix(double dt)
Calculate the discrete system matrices .
Definition: StateSpaceModel.h:164
CCC::StateSpaceModel::~StateSpaceModel
virtual ~StateSpaceModel()=default
Destructor.
CCC::StateSpaceModel::stateEqDisc
StateDimVector stateEqDisc(const StateDimVector &x, const InputDimVector &u) const
Calculate the discrete state equation.
Definition: StateSpaceModel.h:133
CCC::StateSpaceModel::Ad_
Eigen::Matrix< double, StateDim, StateDim > Ad_
Matrix of discrete state equation.
Definition: StateSpaceModel.h:250
CCC::StateSpaceModel::stateEq
StateDimVector stateEq(const StateDimVector &x, const InputDimVector &u) const
Calculate the continuous state equation.
Definition: StateSpaceModel.h:123
CCC::StateSpaceModel< 3, 1, 1 >::OutputDimVector
Eigen::Matrix< double, OutputDim, 1 > OutputDimVector
Type of output vector.
Definition: StateSpaceModel.h:31
CCC::StateSpaceModel::B_
Eigen::Matrix< double, StateDim, InputDim > B_
Matrix of continuous state equation.
Definition: StateSpaceModel.h:232
CCC::StateSpaceModel::dt_
double dt_
Discretization timestep [sec] (zero if discrete coefficients are not initialized)
Definition: StateSpaceModel.h:247
CCC::StateSpaceModel::F_
OutputDimVector F_
Offset vector of observation equation.
Definition: StateSpaceModel.h:244