Drake
system_output.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <memory>
4 #include <set>
5 #include <stdexcept>
6 #include <string>
7 #include <vector>
8 
9 #include "drake/drakeSystemFramework_export.h"
12 
13 namespace drake {
14 namespace systems {
15 
21 // TODO(david-german-tri): Consider moving to its own file.
22 class DRAKESYSTEMFRAMEWORK_EXPORT OutputPortListenerInterface {
23  public:
25 
28  virtual void Invalidate() = 0;
29 };
30 
41 class OutputPort {
42  public:
43  virtual ~OutputPort() = default;
44 
48  dependents_.insert(dependent);
49  }
50 
53  dependents_.erase(dependent);
54  }
55 
58  long long get_version() const { return version_; }
59 
63  ++version_;
64  for (OutputPortListenerInterface* dependent : dependents_)
65  dependent->Invalidate();
66  }
67 
68  protected:
70 
71  private:
72  // OutputPort objects are neither copyable nor moveable.
73  OutputPort(const OutputPort& other) = delete;
74  OutputPort& operator=(const OutputPort& other) = delete;
75  OutputPort(OutputPort&& other) = delete;
76  OutputPort& operator=(OutputPort&& other) = delete;
77 
78  // The rate at which this port produces output, in seconds.
79  // If zero, the port is continuous.
80  double sample_time_sec_{0.};
81 
82  // The list of consumers that should be notified when the value on this
83  // output port changes.
84  std::set<OutputPortListenerInterface*> dependents_;
85 
86  // A counter that is bumped every time this port's value changes.
87  long long version_{0};
88 };
89 
94 template <typename T>
95 class VectorOutputPort : public OutputPort {
96  public:
98  explicit VectorOutputPort(std::unique_ptr<VectorInterface<T>> data)
99  : OutputPort(), vector_data_(std::move(data)) {}
100 
104  return vector_data_.get();
105  }
106 
113  NoteValueModification();
114  return vector_data_.get();
115  }
116 
117  private:
118  // VectorOutputPort objects are neither copyable nor moveable.
119  VectorOutputPort(const VectorOutputPort& other) = delete;
120  VectorOutputPort& operator=(const VectorOutputPort& other) = delete;
121  VectorOutputPort(VectorOutputPort&& other) = delete;
122  VectorOutputPort& operator=(VectorOutputPort&& other) = delete;
123 
124  // The port data for this vector-valued port.
125  std::unique_ptr<VectorInterface<T>> vector_data_;
126 };
127 
132 template <typename T>
134  public:
137  explicit SystemOutput(int num_ports) : ports_(num_ports) {}
138 
142  void set_port(int port_num, std::unique_ptr<OutputPort> port) {
143  RangeCheck(port_num, "reset_port");
144  ports_[port_num] = std::move(port);
145  }
146 
149  int get_num_ports() const { return (int)ports_.size(); }
150 
154  bool is_empty_port(int port_num) const {
155  RangeCheck(port_num, "empty_port");
156  return !ports_[port_num];
157  }
158 
164  bool is_vector_port(int port_num) const {
165  RangeCheck(port_num, "is_vector_port");
166  const OutputPort* port = ports_[port_num].get();
167  if (port == nullptr) return false;
168  return dynamic_cast<const VectorOutputPort<T>*>(port) != nullptr;
169  }
170 
173  const OutputPort& get_port(int port_num) const {
174  RangeCheck(port_num, "get_port");
175  return *ports_[port_num];
176  }
177 
179  OutputPort* get_mutable_port(int port_num) {
180  RangeCheck(port_num, "get_port");
181  return ports_[port_num].get();
182  }
183 
186  const VectorOutputPort<T>& get_vector_port(int port_num) const {
187  const OutputPort& port = get_port(port_num);
188  auto vector_port = dynamic_cast<const VectorOutputPort<T>*>(&port);
189  if (vector_port == nullptr) {
190  throw std::logic_error("SystemOutput::get_vector_port(): Port " +
191  std::to_string(port_num) +
192  " is not a VectorOutputPort.");
193  }
194  return *vector_port;
195  }
196 
200  const VectorOutputPort<T>& port = get_vector_port(port_num);
201  return const_cast<VectorOutputPort<T>*>(&port);
202  }
203 
204  private:
205  void RangeCheck(int port_num, const char* name) const {
206  if (0 <= port_num && port_num < get_num_ports()) return;
207  throw std::out_of_range(GetMethod(name) + "output port " +
208  std::to_string(port_num) +
209  " is out of range (there are " +
210  std::to_string(get_num_ports()) + " ports).");
211  }
212  void RangeNullCheck(int port_num, const char* name) const {
213  RangeCheck(port_num, name);
214  if (!ports_[port_num])
215  throw std::logic_error(GetMethod(name) + "output port " +
216  std::to_string(port_num) + " is empty.");
217  }
218  static std::string GetMethod(const char* name) {
219  using namespace std::string_literals;
220  return "SystemOutput::"s + std::string(name) + "(): "s;
221  }
222 
223  std::vector<std::unique_ptr<OutputPort>> ports_;
224 };
225 
226 } // namespace systems
227 } // namespace drake
VectorInterface is a pure abstract interface that real-valued signals between Systems must satisfy...
Definition: vector_interface.h:25
SystemOutput(int num_ports)
Construct a SystemOutput with room for num_ports OutputPort objects, initially empty.
Definition: system_output.h:137
bool is_empty_port(int port_num) const
Returns true if the indicated port slot is unoccupied.
Definition: system_output.h:154
const VectorInterface< T > * get_vector_data() const
Returns the vector of data in this output port, or nullptr if this is an abstract-valued port...
Definition: system_output.h:103
virtual ~OutputPortListenerInterface()
Definition: system_output.h:24
Definition: constants.h:3
OutputPort * get_mutable_port(int port_num)
Returns a mutable pointer to the indicated port.
Definition: system_output.h:179
VectorOutputPort< T > * get_mutable_vector_port(int port_num)
Returns a mutable pointer to the indicated VectorOutputPort.
Definition: system_output.h:199
const OutputPort & get_port(int port_num) const
Returns a const reference to the indicated port, which must be in range and not empty.
Definition: system_output.h:173
STL namespace.
void set_port(int port_num, std::unique_ptr< OutputPort > port)
Sets or replaces the indicated OutputPort with the given port and takes over ownership.
Definition: system_output.h:142
VectorOutputPort(std::unique_ptr< VectorInterface< T >> data)
Takes ownership of data.
Definition: system_output.h:98
void add_dependent(OutputPortListenerInterface *dependent)
Registers dependent to receive invalidation notifications whenever this output port&#39;s value changes...
Definition: system_output.h:47
An OutputPort represents a data output from a System.
Definition: system_output.h:41
VectorInterface< T > * GetMutableVectorData()
Returns a pointer providing mutable access to the data inside this VectorOutputPort, and updates the version so that Contexts depending on this OutputPort know to invalidate their caches.
Definition: system_output.h:112
bool is_vector_port(int port_num) const
Check whether the indicated port is of type VectorOutputPort<T>; otherwise it is an AbstractOutputPor...
Definition: system_output.h:164
void remove_dependent(OutputPortListenerInterface *dependent)
Unregisters dependent from invalidation notifications.
Definition: system_output.h:52
OutputPort()
Definition: system_output.h:69
std::string to_string(const Eigen::MatrixBase< Derived > &a)
Definition: testUtil.h:29
OutputPortListenerInterface is an interface that consumers of an output port must satisfy to receive ...
Definition: system_output.h:22
A container for all the output ports of a System.
Definition: system_output.h:133
const VectorOutputPort< T > & get_vector_port(int port_num) const
Returns a const reference to the indicated VectorOutputPort.
Definition: system_output.h:186
The OutputPort represents a data output from a System.
Definition: system_output.h:95
long long get_version() const
Returns a positive and monotonically increasing number that is guaranteed to change whenever GetMutab...
Definition: system_output.h:58
void NoteValueModification()
Notify any dependents that the value on this OutputPort has changed, and update the value version her...
Definition: system_output.h:62
int get_num_ports() const
Returns the number of OutputPort objects which may be contained here.
Definition: system_output.h:149