Drake
context3.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <memory>
4 #include <vector>
5 
9 
10 namespace drake {
11 namespace systems {
12 
13 class AbstractSystem3;
14 class InputPort3;
15 class OutputPort3;
16 
23  InputEntryFinder() = default;
25  : subcontext_num(subcontext_num), port_num(port_num), entry(entry) {}
26  InputEntryFinder(const InputEntryFinder& source) { *this = source; }
29  port_num = source.port_num;
30  entry = nullptr;
31  return *this;
32  }
34  InputEntryFinder(InputEntryFinder&& source) { *this = std::move(source); }
37  subcontext_num = source.subcontext_num;
38  port_num = source.port_num;
39  entry = source.entry;
40  new (&source) InputEntryFinder(); // default re-construct source
41  return *this;
42  }
43  int subcontext_num{-1};
44  int port_num{-1};
46 };
47 
54  OutputEntryFinder() = default;
56  : subcontext_num(subcontext_num), location(location), entry(entry) {
57 
58  }
59  OutputEntryFinder(const OutputEntryFinder& source) { *this = source; }
62  location = source.location;
63  entry = nullptr;
64  return *this;
65  }
67  OutputEntryFinder(OutputEntryFinder&& source) { *this = std::move(source); }
70  subcontext_num = source.subcontext_num;
71  location = source.location;
72  entry = source.entry;
73  new (&source) OutputEntryFinder(); // default re-construct source
74  return *this;
75  }
76  int subcontext_num{-1};
77  int location{-1};
79 };
80 
88  public:
89  virtual ~AbstractContext3() {};
90 
95  std::unique_ptr<AbstractContext3> Clone() const {
96  return std::unique_ptr<AbstractContext3>(DoClone());
97  }
98 
101  void SetNumInputPorts(int num_ports) {
102  DRAKE_ABORT_UNLESS(num_ports >= 0);
103  ClearInputPorts();
104  inputs_.resize(num_ports);
105  }
106 
109  void SetNumOutputPorts(int num_ports) {
110  DRAKE_ABORT_UNLESS(num_ports >= 0);
111  ClearOutputPorts();
112  outputs_.resize(num_ports);
113  }
114 
117  DRAKESYSTEMFRAMEWORK_EXPORT
118  void SetInputPort(const AbstractSystem3& system, int port_num);
119 
122  DRAKESYSTEMFRAMEWORK_EXPORT
123  void SetOutputPort(const AbstractSystem3& system, int port_num);
124 
125  int get_num_input_ports() const { return (int)inputs_.size(); }
126  int get_num_output_ports() const { return (int)outputs_.size(); }
127  int get_num_cache_entries() const { return (int)cache_.size(); }
128 
132  const CacheEntry* get_input_entry(int port_num) const {
133  return get_input_entry_finder(port_num).entry;
134  }
135 
139  CacheEntry* get_mutable_input_entry(int port_num) const {
140  return get_input_entry_finder(port_num).entry;
141  }
142 
143  const CacheEntry& get_output_entry(int port_num) const {
144  return *get_output_entry_finder(port_num).entry;
145  }
146 
147  CacheEntry* get_mutable_output_entry(int port_num) const {
148  return get_output_entry_finder(port_num).entry;
149  }
150 
157  int AddSubcontext(std::unique_ptr<AbstractContext3> subcontext) {
158  const int subcontext_num = get_num_subcontexts();
159  subcontext->set_owner(this, subcontext_num);
160  subcontexts_.push_back(std::move(subcontext));
161  return subcontext_num;
162  }
163 
167  int get_num_subcontexts() const { return (int)subcontexts_.size(); }
168 
172  const AbstractContext3& get_subcontext(int index) const {
173  return *subcontexts_[index];
174  }
175 
180  return subcontexts_[index].get();
181  }
182 
185  const AbstractContext3* get_parent_context() const { return owner_; }
186 
190 
194  int get_subcontext_num() const { return subcontext_num_; }
195 
196 
199  const AbstractSystem3& find_my_subsystem(
200  const AbstractSystem3& some_subsystem) const;
201 
207  AbstractSystem3* some_subsystem) const {
208  return const_cast<AbstractSystem3*>(&find_my_subsystem(*some_subsystem));
209  }
210 
211 
216  if (!get_parent_context()) return *this;
217  return get_parent_context()->get_root_context();
218  }
219 
224  return const_cast<AbstractContext3*>(&get_root_context());
225  }
226 
229  protected:
231  AbstractContext3() = default;
232 
236  : inputs_(source.inputs_),
237  outputs_(source.outputs_),
238  cache_(source.cache_) {
239  // TODO(sherm1) input and output pointers are null now an need fixup.
240 
241  // TODO(sherm1) copy subcontexts
242  //for (const auto& sub : source.subcontexts_)
243  // subcontexts_.emplace_back(sub->Clone());
244  }
245 
248  virtual AbstractContext3* DoClone() const = 0;
249 
250  private:
251  friend class AbstractSystem3;
252 
253  const InputEntryFinder& get_input_entry_finder(int port_num) const {
254  return inputs_[port_num];
255  }
256 
257  const OutputEntryFinder& get_output_entry_finder(int port_num) const {
258  return outputs_[port_num];
259  }
260 
261  InputEntryFinder* get_mutable_input_entry_finder(int port_num) {
262  return &inputs_[port_num];
263  }
264 
265  OutputEntryFinder* get_mutable_output_entry_finder(int port_num) {
266  return &outputs_[port_num];
267  }
268 
269  // Removes all the input ports, and deregisters them from the output ports
270  // on which they depend.
271  // TODO(sherm1) Actually do that.
272  void ClearInputPorts() { inputs_.clear(); }
273 
274  // Removes all the output ports, and disconnects any input ports that might
275  // have been plugged in to them.
276  // TODO(sherm1) Actually do that.
277  void ClearOutputPorts() { outputs_.clear(); }
278 
285  const AbstractContext3& find_subcontext(const std::vector<int>& path,
286  int start = 0) const {
287  if (start == (int)path.size()) return *this;
288  return get_subcontext(path[start]).find_subcontext(path, start + 1);
289  }
290 
293  AbstractContext3* find_mutable_subcontext(const std::vector<int>& path) {
294  return const_cast<AbstractContext3*>(&find_subcontext(path));
295  }
296 
304  std::vector<int> get_path_from_root_context() const {
305  std::vector<int> path;
306  if (get_parent_context()) {
307  path = get_parent_context()->get_path_from_root_context();
308  DRAKE_ASSERT(get_subcontext_num() >= 0);
309  path.push_back(get_subcontext_num());
310  }
311  return path;
312  }
313 
314  // Set backpointer to parent context and subcontext number by which we are
315  // known there.
316  void set_owner(AbstractContext3* parent, int subcontext_num) {
317  owner_ = parent;
318  subcontext_num_ = subcontext_num;
319  }
320 
321  std::vector<InputEntryFinder> inputs_;
322  // TODO(sherm1) Add parameter entries.
323 
324  std::vector<OutputEntryFinder> outputs_;
325 
326 
327  // The cache, consisting of a pool of cache entries that are individually
328  // validated and invalidated, and upon which other calculations may depend.
329  mutable std::vector<CacheEntry> cache_;
330 
331 
332  // Entries here correspond directly to System subsystems, using the
333  // same index. Any of these may be context diagrams recursively.
334  std::vector<std::unique_ptr<AbstractContext3>> subcontexts_;
335 
336  // If this context is a subcontext in a context diagram, this is set to the
337  // owning parent context, with the subcontext number as known to the parent.
338  AbstractContext3* owner_{};
339  int subcontext_num_{-1};
340 };
341 
344 // TODO(sherm1) Add step information.
345 template <typename T>
346 struct StepInfo {
349  // TODO(sherm1): Consider whether this is sufficiently robust.
350  T time_sec{};
351 };
352 
369 // TODO(sherm1): Manage cache invalidation.
370 template <typename T>
371 class Context3 : public AbstractContext3 {
372  public:
373  Context3() {}
374  ~Context3() override {}
375 
377  const T& get_time() const { return get_step_info().time_sec; }
378 
380  void set_time(const T& time_sec) {
381  get_mutable_step_info()->time_sec = time_sec;
382  }
383 
384  //const State<T>& get_state() const { return state_; }
385 
388  //State<T>* get_mutable_state() { return &state_; }
389 
394  std::unique_ptr<Context3<T>> Clone() const {
395  return std::unique_ptr<Context3<T>>(DoClone());
396  }
397 
402  Context3(const Context3& source) : AbstractContext3(source) {
403 
404  }
405 
406  protected:
407  // TODO(sherm1) Fix this.
408 
412  Context3<T>* DoClone() const override {
413  Context3<T>* context = new Context3<T>();
414 
415  // TODO(sherm1)
416 
418  //const ContinuousState<T>& xc = *this->get_state().continuous_state;
419  //const int num_q = xc.get_generalized_position().size();
420  //const int num_v = xc.get_generalized_velocity().size();
421  //const int num_z = xc.get_misc_continuous_state().size();
422  //const LeafStateVector<T>& xc_vector =
423  // dynamic_cast<const LeafStateVector<T>&>(xc.get_state());
424  //context->get_mutable_state()->continuous_state.reset(
425  // new ContinuousState<T>(xc_vector.Clone(), num_q, num_v, num_z));
426 
429  //for (const auto& port : this->inputs_) {
430  // context->inputs_.emplace_back(new FreestandingInputPort<T>(
431  // port->get_vector_data()->Clone(), port->get_sample_time_sec()));
432  //}
433 
435  //*context->get_mutable_step_info() = this->get_step_info();
436  //*context->get_mutable_cache() = this->get_cache();
437  return context;
438  }
439 
440  private:
441  // Returns a const reference to current time and step information.
442  const StepInfo<T>& get_step_info() const { return step_info_; }
443 
444  // Provides writable access to time and step information, with the side
445  // effect of invaliding any computation that is dependent on them.
446  // TODO(david-german-tri) Invalidate all cached time- and step-dependent
447  // computations.
448  StepInfo<T>* get_mutable_step_info() { return &step_info_; }
449 
450  // Context3 objects are neither assignable nor moveable, but they are
451  // copy constructible.
452  Context3& operator=(const Context3& other) = delete;
453  Context3(Context3&& other) = delete;
454  Context3& operator=(Context3&& other) = delete;
455 
456  // Typed independent quantities: time and state.
457 
458  // Current time and step information. Think of this as a "time port".
459  // TODO(sherm1) Consider literally making this a port.
460  StepInfo<T> step_info_;
461 
462  // The internal state of the System.
463  //State<T> state_;
464 
465  // Typed dependent quantities: state derivatives, discrete state updates.
466  // TODO(sherm1) These should be VectorCacheEntry<T>.
467 
468  // Continuous state time derivative values (numerical vectors). Together
469  // these are xc_dot.
470  mutable CacheEntry qdot_, udot_, zdot_;
471 
472  // Second time-derivative of the configuration states q (numerical vector).
473  mutable CacheEntry qdotdot_;
474 
475  // Discrete state updates (numerical vector). This is xd_hat.
476  mutable CacheEntry updates_;
477 };
478 
479 } // namespace systems
480 } // namespace drake
An abstract superclass for the Context3 objects for dynamical systems, encapsulating functionality th...
Definition: context3.h:87
int subcontext_num
-1 means this context.
Definition: context3.h:76
virtual ~AbstractContext3()
Definition: context3.h:89
int get_subcontext_num() const
If this context is a subcontext of a parent context, return the subcontext number by which that paren...
Definition: context3.h:194
const AbstractContext3 & get_root_context() const
Find the root context of the tree of which this subcontext is a member.
Definition: context3.h:215
int get_num_subcontexts() const
Returns the current number of subcontexts contained in this context.
Definition: context3.h:167
Definition: constants.h:3
InputEntryFinder()=default
OutputEntryFinder(OutputEntryFinder &&source)
Move constructor preserves all values and clears the source.
Definition: context3.h:67
int location
Port number for subcontext, or entry if local.
Definition: context3.h:77
Context3()
Definition: context3.h:373
Context3(const Context3 &source)
Copy constructor makes a deep copy of the source Context3, and also copies the current values of time...
Definition: context3.h:402
InputEntryFinder & operator=(InputEntryFinder &&source)
Move assignment preserves all values and clears the source.
Definition: context3.h:36
const AbstractContext3 * get_parent_context() const
Returns a const pointer to the parent context that owns this one, or nullptr if this is a root contex...
Definition: context3.h:185
CacheEntry * get_mutable_input_entry(int port_num) const
Return a mutable pointer to the cache entry that is providing the value for the given input port...
Definition: context3.h:139
int get_num_output_ports() const
Definition: context3.h:126
const AbstractContext3 & get_subcontext(int index) const
Returns a const reference to one of the contained subcontexts, using the index reflecting the order i...
Definition: context3.h:172
int AddSubcontext(std::unique_ptr< AbstractContext3 > subcontext)
Add a subcontext as a child of this context.
Definition: context3.h:157
const CacheEntry & get_output_entry(int port_num) const
Definition: context3.h:143
int get_num_cache_entries() const
Definition: context3.h:127
There is one of these corresponding to every OutputPort3 in the System3 that created the containing C...
Definition: context3.h:53
std::unique_ptr< Context3< T > > Clone() const
Returns writable access to the State.
Definition: context3.h:394
There is one of these corresponding to every InputPort3 in the System3 that created the containing Co...
Definition: context3.h:22
#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
~Context3() override
Definition: context3.h:374
Provides Drake&#39;s assertion implementation.
#define DRAKE_ABORT_UNLESS(condition)
Evaluates condition and iff the value is false will ::abort() the program with a message showing at l...
Definition: drake_assert.h:39
AbstractContext3 * get_mutable_parent_context()
Returns a mutable pointer to the parent context that owns this one, or nullptr if this is a root cont...
Definition: context3.h:189
InputEntryFinder(InputEntryFinder &&source)
Move constructor preserves all values and clears the source.
Definition: context3.h:34
InputEntryFinder & operator=(const InputEntryFinder &source)
Definition: context3.h:27
OutputEntryFinder & operator=(const OutputEntryFinder &source)
Definition: context3.h:60
int port_num
Port number as understood by the subcontext.
Definition: context3.h:44
An abstract superclass for dynamical systems, encapsulating functionality that is independent of the ...
Definition: system3.h:68
void SetNumInputPorts(int num_ports)
Allocate input port entries corresponding to a System3&#39;s InputPort3 objects.
Definition: context3.h:101
std::unique_ptr< AbstractContext3 > Clone() const
Returns a deep copy of this Context3.
Definition: context3.h:95
int get_num_input_ports() const
Definition: context3.h:125
Context3< T > * DoClone() const override
The Context implementation for Diagrams must override this method, since the state of a Diagram will ...
Definition: context3.h:412
const CacheEntry * get_input_entry(int port_num) const
Return a const pointer to the cache entry that is providing the value for the given input port...
Definition: context3.h:132
OutputEntryFinder(int subcontext_num, int location, CacheEntry *entry)
Definition: context3.h:55
void set_time(const T &time_sec)
Set the current time in seconds.
Definition: context3.h:380
int subcontext_num
-1 means this context.
Definition: context3.h:43
CacheEntry * get_mutable_output_entry(int port_num) const
Definition: context3.h:147
The context is a container for all data necessary to uniquely determine the results of computations p...
Definition: context3.h:371
Contains information about the independent variable including time and step number.
Definition: context.h:19
InputEntryFinder(int subcontext_num, int port_num, CacheEntry *entry)
Definition: context3.h:24
AbstractContext3 * get_mutable_root_context()
Get a mutable pointer to the root context of the tree of which this subcontext is a member...
Definition: context3.h:223
OutputEntryFinder(const OutputEntryFinder &source)
Definition: context3.h:59
const T & get_time() const
Returns the current time in seconds.
Definition: context3.h:377
AbstractContext3(const AbstractContext3 &source)
Copy the base class data members and preserve the input and parameter port values.
Definition: context3.h:235
AbstractSystem3 * find_my_mutable_subsystem(AbstractSystem3 *some_subsystem) const
Get mutable access to this subcontext&#39;s subsystem given mutable access to any other subcontext&#39;s subs...
Definition: context3.h:206
void SetNumOutputPorts(int num_ports)
Allocate output port entries corresponding to a System3&#39;s OutputPort3 objects.
Definition: context3.h:109
AbstractContext3 * get_mutable_subcontext(int index)
Returns a mutable pointer to one of the contained subcontexts, using the index reflecting the order i...
Definition: context3.h:179
CacheEntry * entry
Convenience pointer to output if connected.
Definition: context3.h:45
OutputEntryFinder & operator=(OutputEntryFinder &&source)
Move assignment preserves all values and clears the source.
Definition: context3.h:69
InputEntryFinder(const InputEntryFinder &source)
Definition: context3.h:26
Each cache entry contains:
Definition: cache3.h:29