Drake
feedback_system.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <memory>
4 
6 #include "drake/core/Function.h"
7 #include "drake/core/Gradient.h"
8 #include "drake/core/Vector.h"
9 #include "drake/systems/System.h"
10 
11 namespace Drake {
12 
23 template <class System1, class System2>
25  public:
26  template <typename ScalarType>
27  using StateVector1 = typename System1::template StateVector<ScalarType>;
28  template <typename ScalarType>
29  using StateVector2 = typename System2::template StateVector<ScalarType>;
30  template <typename ScalarType>
31  using StateVector = typename CombinedVectorUtil<
32  System1::template StateVector,
33  System2::template StateVector>::template type<ScalarType>;
34  template <typename ScalarType>
35  using InputVector = typename System1::template InputVector<ScalarType>;
36  template <typename ScalarType>
37  using OutputVector = typename System1::template OutputVector<ScalarType>;
39 
40  typedef std::shared_ptr<System1> System1Ptr;
41  typedef std::shared_ptr<System2> System2Ptr;
42 
43  static_assert(
44  std::is_same<typename System1::template OutputVector<double>,
45  typename System2::template InputVector<double>>::value,
46  "System 2 input vector must match System 1 output vector");
47  static_assert(
48  std::is_same<typename System2::template OutputVector<double>,
49  typename System1::template InputVector<double>>::value,
50  "System 1 input vector must match System 2 output vector");
51 
52  FeedbackSystem(const System1Ptr& _sys1, const System2Ptr& _sys2)
53  : sys1(_sys1), sys2(_sys2) {
54  if (sys1->isDirectFeedthrough() && sys2->isDirectFeedthrough()) {
55  throw std::runtime_error("Algebraic loop in FeedbackSystem");
56  }
57  }
58 
59  template <typename ScalarType>
60  StateVector<ScalarType> dynamics(const ScalarType& t,
61  const StateVector<ScalarType>& x,
62  const InputVector<ScalarType>& u) const {
63  const auto& x1 = util::first(x);
64  const auto& x2 = util::second(x);
65  OutputVector<ScalarType> y1;
66  InputVector<ScalarType> y2;
67  InputVector<ScalarType> u1;
68  subsystemOutputs(t, x1, x2, u, true, &y1, &y2, &u1);
69  return util::combine(
70  sys1->dynamics(t, x1, u1),
71  sys2->dynamics(t, x2, y1));
72  }
73 
74  template <typename ScalarType>
75  OutputVector<ScalarType> output(const ScalarType& t,
76  const StateVector<ScalarType>& x,
77  const InputVector<ScalarType>& u) const {
78  const auto& x1 = util::first(x);
79  const auto& x2 = util::second(x);
80  OutputVector<ScalarType> y1;
81  InputVector<ScalarType> y2;
82  InputVector<ScalarType> u1;
83  subsystemOutputs(t, x1, x2, u, false, &y1, &y2, &u1);
84  return y1;
85  }
86 
87  bool isTimeVarying() const {
88  return sys1->isTimeVarying() || sys2->isTimeVarying();
89  }
90  bool isDirectFeedthrough() const { return sys1->isDirectFeedthrough(); }
91  size_t getNumStates() const {
92  return Drake::getNumStates(*sys1) + Drake::getNumStates(*sys2);
93  }
94  size_t getNumInputs() const { return Drake::getNumInputs(*sys1); }
95  size_t getNumOutputs() const { return Drake::getNumOutputs(*sys1); }
96 
97  const System1Ptr& getSys1() const { return sys1; }
98 
99  const System2Ptr& getSys2() const { return sys2; }
100 
103  return util::combine(getInitialState(*(sys.sys1)),
104  getInitialState(*(sys.sys2)));
105  }
106 
107  private:
108  // x1 is sys1 state.
109  // x2 is sys2 state.
110  // u is the feedback_system's input.
112  // y1 is sys1's output.
113  // y2 is sys2's output.
114  // u1 is the input to sys1 (u + y2).
115  //
116  // If want_y2_u1 is true, y2 and u1 are always computed.
117  // If want_y2_u1 is false, y2 and u1 may or may not be computed.
118  template <typename ScalarType>
119  void subsystemOutputs(const ScalarType& t,
120  const StateVector1<ScalarType>& x1,
121  const StateVector2<ScalarType>& x2,
122  const InputVector<ScalarType>& u,
123  bool want_y2_u1,
124  OutputVector<ScalarType>* y1,
125  InputVector<ScalarType>* y2,
126  InputVector<ScalarType>* u1) const {
127  if (!sys1->isDirectFeedthrough()) {
128  // sys1->output doesn't use u1, so it's okay that it isn't filled in yet.
129  *y1 = sys1->output(t, x1, *u1);
130  if (want_y2_u1) {
131  *y2 = sys2->output(t, x2, *y1);
132  *u1 = static_cast<InputVector<ScalarType>>(toEigen(*y2) + toEigen(u));
133  }
134  } else {
135  DRAKE_ASSERT(!sys2->isDirectFeedthrough()); // Per our constructor.
136  // sys2->output doesn't use y1, so it's okay that it isn't filled in yet.
137  *y2 = sys2->output(t, x2, *y1);
138  *u1 = static_cast<InputVector<ScalarType>>(toEigen(*y2) + toEigen(u));
139  *y1 = sys1->output(t, x1, *u1);
140  }
141  }
142 
143  System1Ptr sys1;
144  System2Ptr sys2;
145 };
146 
151 template <typename System1, typename System2>
152 std::shared_ptr<FeedbackSystem<System1, System2>> feedback(
153  const std::shared_ptr<System1>& sys1,
154  const std::shared_ptr<System2>& sys2) {
155  return std::make_shared<FeedbackSystem<System1, System2>>(sys1, sys2);
156 }
157 
158 } // namespace Drake
size_t getNumStates() const
Definition: feedback_system.h:91
StateVector< ScalarType > dynamics(const ScalarType &t, const StateVector< ScalarType > &x, const InputVector< ScalarType > &u) const
Definition: feedback_system.h:60
std::vector< Number > x
Definition: IpoptSolver.cpp:169
typename System1::template StateVector< ScalarType > StateVector1
Definition: feedback_system.h:27
typename System1::template InputVector< ScalarType > InputVector
Definition: feedback_system.h:35
std::shared_ptr< System1 > System1Ptr
Definition: feedback_system.h:40
const System2Ptr & getSys2() const
Definition: feedback_system.h:99
NOTE: The contents of this class are for the most part direct ports of drake/systems/plants//inverseK...
Definition: Function.h:14
typename System1::template OutputVector< ScalarType > OutputVector
Definition: feedback_system.h:37
const System1Ptr & getSys1() const
Definition: feedback_system.h:97
bool isTimeVarying() const
Definition: feedback_system.h:87
FeedbackSystem<System1,System2>
Definition: feedback_system.h:24
FeedbackSystem(const System1Ptr &_sys1, const System2Ptr &_sys2)
Definition: feedback_system.h:52
std::size_t getNumOutputs(const System &sys)
getNumOutputs()
Definition: System.h:162
static Vector1< ScalarType > first(const typename helper::template type< ScalarType > &vec)
Definition: Vector.h:292
static double * t
Definition: inverseKinSnoptBackend.cpp:62
static helper::template type< ScalarType > combine(const Vector1< ScalarType > &vec1, const Vector2< ScalarType > &vec2)
Definition: Vector.h:304
typename CombinedVectorUtil< System1::template StateVector, System2::template StateVector >::template type< ScalarType > StateVector
Definition: feedback_system.h:33
#define DRAKE_ASSERT(condition)
DRAKE_ASSERT(condition) is similar to the built-in assert(condition) from the C++ system header <cas...
Definition: drake_assert.h:35
std::shared_ptr< System2 > System2Ptr
Definition: feedback_system.h:41
typename System2::template StateVector< ScalarType > StateVector2
Definition: feedback_system.h:29
Provides Drake&#39;s assertion implementation.
CombinedVectorUtil< StateVector1, StateVector2 > util
Definition: feedback_system.h:38
std::size_t getNumStates(const System &sys)
getNumStates()
Definition: System.h:108
size_t getNumOutputs() const
Definition: feedback_system.h:95
OutputVector< ScalarType > output(const ScalarType &t, const StateVector< ScalarType > &x, const InputVector< ScalarType > &u) const
Definition: feedback_system.h:75
std::size_t getNumInputs(const System &sys)
getNumInputs()
Definition: System.h:135
std::shared_ptr< FeedbackSystem< System1, System2 > > feedback(const std::shared_ptr< System1 > &sys1, const std::shared_ptr< System2 > &sys2)
feedback(sys1, sys2)
Definition: feedback_system.h:152
CombinedVectorUtil.
Definition: Vector.h:284
friend StateVector< double > getInitialState(const FeedbackSystem< System1, System2 > &sys)
Definition: feedback_system.h:101
static Vector2< ScalarType > second(const typename helper::template type< ScalarType > &vec)
Definition: Vector.h:298
THIS FILE IS DEPRECATED.
const Eigen::Matrix< ScalarType, Rows, 1 > & toEigen(const Eigen::Matrix< ScalarType, Rows, 1 > &vec)
Definition: Vector.h:61
size_t getNumInputs() const
Definition: feedback_system.h:94
bool isDirectFeedthrough() const
Definition: feedback_system.h:90