Drake
context_base.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <cstdint>
5 #include <memory>
6 #include <string>
7 #include <utility>
8 #include <vector>
9 
11 #include "drake/common/unused.h"
16 
17 namespace drake {
18 namespace systems {
19 
20 #ifndef DRAKE_DOXYGEN_CXX
21 namespace detail {
22 // This provides SystemBase limited "friend" access to ContextBase.
23 class SystemBaseContextBaseAttorney;
24 } // namespace detail
25 #endif
26 
27 /** Provides non-templatized Context functionality shared by the templatized
28 derived classes. That includes caching, dependency tracking, and management
29 of local values for fixed input ports.
30 
31 Terminology: in general a Drake System is a tree structure composed of
32 "subsystems", which are themselves System objects. The corresponding Context is
33 a parallel tree structure composed of "subcontexts", which are themselves
34 Context objects. There is a one-to-one correspondence between subsystems and
35 subcontexts. Within a given System (Context), its child subsystems (subcontexts)
36 are indexed using a SubsystemIndex; there is no separate SubcontextIndex since
37 the numbering must be identical. */
38 class ContextBase : public internal::ContextMessageInterface {
39  public:
40  /** @name Does not allow copy, move, or assignment. */
41  /** @{ */
42  // Copy constructor is used only to facilitate implementation of Clone()
43  // in derived classes.
44  ContextBase(ContextBase&&) = delete;
45  ContextBase& operator=(const ContextBase&) = delete;
46  ContextBase& operator=(ContextBase&&) = delete;
47  /** @} */
48 
49  /** Creates an identical copy of the concrete context object. */
50  std::unique_ptr<ContextBase> Clone() const;
51 
52  ~ContextBase() override;
53 
54  /** (Debugging) Disables caching recursively for this context
55  and all its subcontexts. Disabling forces every `Eval()` method to perform a
56  full calculation rather than returning the cached one. Results should be
57  identical with or without caching, except for performance. If they are not,
58  there is likely a problem with (a) the specified dependencies for some
59  calculation, or (b) a misuse of references into cached values that hides
60  modifications from the caching system, or (c) a bug in the caching system. The
61  `is_disabled` flags are independent of the `out_of_date` flags, which continue
62  to be maintained even when caching is disabled (though they are ignored). */
63  void DisableCaching() const {
64  PropagateCachingChange(*this, &Cache::DisableCaching);
65  }
66 
67  /** (Debugging) Re-enables caching recursively for this context and all its
68  subcontexts. The `is_disabled` flags are independent of the `out_of_date`
69  flags, which continue to be maintained even when caching is disabled (though
70  they are ignored). Hence re-enabling the cache with this method may result in
71  some entries being already considered up to date. See
72  SetAllCacheEntriesOutOfDate() if you want to ensure that caching restarts with
73  everything out of date. You might want to do that, for example, for
74  repeatability or because you modified something in the debugger and want to
75  make sure it gets used. */
76  void EnableCaching() const {
77  PropagateCachingChange(*this, &Cache::EnableCaching);
78  }
79 
80  /** (Debugging) Marks all cache entries out of date, recursively for this
81  context and all its subcontexts. This forces the next `Eval()` request for
82  each cache entry to perform a full calculation rather than returning the
83  cached one. After that first recalculation, normal caching behavior resumes
84  (assuming the cache is not disabled). Results should be identical whether this
85  is called or not, since the caching system should be maintaining this flag
86  correctly. If they are not, see the documentation for SetIsCacheDisabled() for
87  suggestions. */
89  PropagateCachingChange(*this, &Cache::SetAllEntriesOutOfDate);
90  }
91 
92  /** Returns the local name of the subsystem for which this is the Context.
93  This is intended primarily for error messages and logging.
94  @see SystemBase::GetSystemName() for details.
95  @see GetSystemPathname() if you want the full name. */
96  const std::string& GetSystemName() const final {
97  return system_name_.empty() ? internal::SystemMessageInterface::no_name()
98  : system_name_;
99  }
100 
101  /** Returns the full pathname of the subsystem for which this is the Context.
102  This is intended primarily for error messages and logging.
103  @see SystemBase::GetSystemPathname() for details. */
104  std::string GetSystemPathname() const final;
105 
106  /** Returns a const reference to this subcontext's cache. */
107  const Cache& get_cache() const {
108  return cache_;
109  }
110 
111  /** (Advanced) Returns a mutable reference to this subcontext's cache. Note
112  that this method is const because the cache is always writable.
113  @warning Writing directly to the cache does not automatically propagate
114  invalidations to downstream dependents of a contained cache entry, because
115  invalidations would normally have been propagated when the cache entry itself
116  went out of date. Cache entries are updated automatically when needed via
117  their `Calc()` methods; most users should not bypass that mechanism by using
118  this method. */
120  return cache_;
121  }
122 
123  /** Returns a const reference to a DependencyTracker in this subcontext.
124  Advanced users and internal code can use the returned reference to issue value
125  change notifications -- mutable access is not required for that purpose. */
127  return graph_.get_tracker(ticket);
128  }
129 
130  /** Returns a mutable reference to a DependencyTracker in this subcontext.
131  (You do not need mutable access just to issue value change notifications.) */
133  return graph_.get_mutable_tracker(ticket);
134  }
135 
136  /** Returns a const reference to the collection of value trackers within
137  this subcontext. Together these form the dependency subgraph for the values
138  in this subcontext, plus edges leading to neighboring trackers. */
140  return graph_;
141  }
142 
143  /** Returns a mutable reference to the dependency graph. */
145  return graph_;
146  }
147 
148  /** Returns the number of input ports in this context. */
149  int get_num_input_ports() const {
150  DRAKE_ASSERT(input_port_tickets_.size() == input_port_values_.size());
151  return static_cast<int>(input_port_tickets_.size());
152  }
153 
154  /** Returns the number of output ports represented in this context. */
155  int get_num_output_ports() const {
156  return static_cast<int>(output_port_tickets_.size());
157  }
158 
159  /** Returns the dependency ticket associated with a particular input port. */
161  DRAKE_DEMAND(port_num < get_num_input_ports());
162  return input_port_tickets_[port_num];
163  }
164 
165  /** Returns the dependency ticket associated with a particular output port. */
167  DRAKE_DEMAND(port_num < get_num_output_ports());
168  return output_port_tickets_[port_num];
169  }
170 
171  /** Connects the input port at `index` to a FixedInputPortValue with
172  the given abstract `value`. Returns a reference to the allocated
173  FixedInputPortValue that will remain valid until this input port's value
174  source is replaced or the Context is destroyed. You may use that reference to
175  modify the input port's value using the appropriate FixedInputPortValue
176  method, which will ensure that invalidation notifications are delivered.
177 
178  This is the most general way to provide a value (type-erased) for an
179  unconnected input port. See `Context<T>` for more-convenient overloads of
180  FixInputPort() for vector values with elements of type T.
181 
182  @pre `index` selects an existing input port of this Context. */
183  FixedInputPortValue& FixInputPort(
184  int index, std::unique_ptr<AbstractValue> value);
185 
186  /** Same as above method but the value is passed by const reference instead
187  of by unique_ptr. The port will contain a copy of the `value` (not retain a
188  pointer to the `value`). */
189  FixedInputPortValue& FixInputPort(int index, const AbstractValue& value) {
190  return FixInputPort(index, value.Clone());
191  }
192 
193  /** For input port `index`, returns a const FixedInputPortValue if the port is
194  fixed, otherwise nullptr.
195  @pre `index` selects an existing input port of this Context. */
197  DRAKE_DEMAND(0 <= index && index < get_num_input_ports());
198  return input_port_values_[index].get();
199  }
200 
201  /** For input port `index`, returns a mutable FixedInputPortValue if the port
202  is fixed, otherwise nullptr.
203  @pre `index` selects an existing input port of this Context. */
205  DRAKE_DEMAND(0 <= index && index < get_num_input_ports());
206  return input_port_values_[index].get_mutable();
207  }
208 
209  /** (Internal use only) Returns the next change event serial number that is
210  unique for this entire Context tree, not just this subcontext. This number
211  is not reset after a Context is copied but continues to count up. */
213  // First search up to find the root Context (typically not far).
214  // TODO(sherm1) Consider precalculating this for faster access.
215  ContextBase* context = this;
216  while (context->parent_) {
217  // Only a root context has a non-negative change event value.
218  DRAKE_ASSERT(context->current_change_event_ == -1);
219  context = context->parent_;
220  }
221  DRAKE_ASSERT(context->current_change_event_ >= 0);
222  return ++context->current_change_event_;
223  }
224 
225  protected:
226  /** Default constructor creates an empty ContextBase but initializes all the
227  built-in dependency trackers that are the same in every System (like time,
228  q, all states, all inputs, etc.). We can't allocate trackers for individual
229  discrete & abstract states, parameters, or input ports since we don't yet
230  know how many there are. */
231  ContextBase() : cache_(this), graph_(this) {
232  CreateBuiltInTrackers();
233  }
234 
235  /** Copy constructor takes care of base class data members, but _does not_ fix
236  up base class pointers. Derived classes must implement copy constructors that
237  delegate to this one for use in their DoCloneWithoutPointers()
238  implementations. The cache and dependency graph are copied, but any pointers
239  contained in the source are left null in the copy. */
240  ContextBase(const ContextBase&) = default;
241 
242  /** @name Add dependency tracking resources (Internal use only)
243  Methods in this group are used by SystemBase and unit testing while creating
244  a Context that can track dependencies for a given System. Although these
245  methods are protected, SystemBase is granted permission to invoke them (via
246  an attorney class). */
247  //@{
248 
249  /** Adds the next input port. Expected index is supplied along with the
250  assigned ticket. Subscribes the "all input ports" tracker to this one. */
251  void AddInputPort(InputPortIndex expected_index, DependencyTicket ticket);
252 
253  /** Adds the next output port. Expected index is supplied along with the
254  assigned ticket. */
255  void AddOutputPort(
256  OutputPortIndex expected_index, DependencyTicket ticket,
257  const internal::OutputPortPrerequisite& prerequisite);
258 
259  /** Adds a ticket to the list of discrete state tickets. */
261  discrete_state_tickets_.push_back(ticket);
262  }
263 
264  /** Adds a ticket to the list of abstract state tickets. */
266  abstract_state_tickets_.push_back(ticket);
267  }
268 
269  /** Adds a ticket to the list of numeric parameter tickets. */
271  numeric_parameter_tickets_.push_back(ticket);
272  }
273 
274  /** Adds a ticket to the list of abstract parameter tickets. */
276  abstract_parameter_tickets_.push_back(ticket);
277  }
278  //@}
279 
280  /// @anchor context_base_change_notification_methods
281  /** @name Change notification methods (Internal use only)
282  These "Note" methods are used by framework-internal derived classes to effect
283  change notifications that propagate down from a DiagramContext (where the
284  change is initiated) through all its subcontexts, recursively. Such
285  notification sweeps result in the "out of date" flag being set in each of
286  the affected cache entry values. Each of these "Note" methods methods affects
287  only the local context, but all have identical signatures so can be passed
288  down the context tree to operate on every subcontext. The `change_event`
289  argument should be the result of the start_new_change_event() method. */
290  //@{
291 
292  /** Notifies the local time tracker that time may have changed. */
293  void NoteTimeChanged(int64_t change_event) {
294  get_tracker(DependencyTicket(internal::kTimeTicket))
295  .NoteValueChange(change_event);
296  }
297 
298  /** Notifies the local accuracy tracker that the accuracy setting
299  may have changed. */
300  void NoteAccuracyChanged(int64_t change_event) {
301  get_tracker(DependencyTicket(internal::kAccuracyTicket))
302  .NoteValueChange(change_event);
303  }
304 
305  /** Notifies the local continuous, discrete, and abstract state trackers that
306  each of them may have changed, likely because someone has asked to modify the
307  whole state x. */
308  void NoteAllStateChanged(int64_t change_event) {
309  NoteAllContinuousStateChanged(change_event);
310  NoteAllDiscreteStateChanged(change_event);
311  NoteAllAbstractStateChanged(change_event);
312  }
313 
314  /** Notifies the local q, v, and z trackers that each of them may have
315  changed, likely because someone has asked to modify continuous state xc. */
316  void NoteAllContinuousStateChanged(int64_t change_event) {
317  NoteAllQChanged(change_event);
318  NoteAllVChanged(change_event);
319  NoteAllZChanged(change_event);
320  }
321 
322  /** Notifies the local q tracker that the q's may have changed. */
323  void NoteAllQChanged(int64_t change_event) {
324  get_tracker(DependencyTicket(internal::kQTicket))
325  .NoteValueChange(change_event);
326  }
327 
328  /** Notifies the local v tracker that the v's may have changed. */
329  void NoteAllVChanged(int64_t change_event) {
330  get_tracker(DependencyTicket(internal::kVTicket))
331  .NoteValueChange(change_event);
332  }
333 
334  /** Notifies the local z tracker that the z's may have changed. */
335  void NoteAllZChanged(int64_t change_event) {
336  get_tracker(DependencyTicket(internal::kZTicket))
337  .NoteValueChange(change_event);
338  }
339 
340  /** Notifies each local discrete state group tracker that the value of
341  the discrete state group it manages may have changed. If there are no discrete
342  state groups owned by this context, nothing happens. A DiagramContext does
343  not own any discrete state groups. */
344  void NoteAllDiscreteStateChanged(int64_t change_event) {
345  for (auto ticket : discrete_state_tickets_)
346  get_tracker(ticket).NoteValueChange(change_event);
347  }
348 
349  /** Notifies each local abstract state variable tracker that the value of the
350  abstract state variable it manages may have changed. If there are no abstract
351  state variables owned by this context, nothing happens. A DiagramContext does
352  not own any abstract state variables. */
353  void NoteAllAbstractStateChanged(int64_t change_event) {
354  for (auto ticket : abstract_state_tickets_)
355  get_tracker(ticket).NoteValueChange(change_event);
356  }
357 
358  /** Notifies the local numeric and abstract parameter trackers that each of
359  them may have changed, likely because someone asked to modify all the
360  parameters. */
361  void NoteAllParametersChanged(int64_t change_event) {
362  NoteAllNumericParametersChanged(change_event);
363  NoteAllAbstractParametersChanged(change_event);
364  }
365 
366  /** Notifies each local numeric parameter tracker that the value of the
367  parameter it manages may have changed. If there are no numeric parameters
368  owned by this context, nothing happens. A DiagramContext does not own any
369  parameters. */
370  void NoteAllNumericParametersChanged(int64_t change_event) {
371  for (auto ticket : numeric_parameter_tickets_)
372  get_tracker(ticket).NoteValueChange(change_event);
373  }
374 
375  /** Notifies each local abstract parameter tracker that the value of the
376  parameter it manages may have changed. If there are no abstract parameters
377  owned by this context, nothing happens. A DiagramContext does not own any
378  parameters. */
379  void NoteAllAbstractParametersChanged(int64_t change_event) {
380  for (auto ticket : abstract_parameter_tickets_)
381  get_tracker(ticket).NoteValueChange(change_event);
382  }
383  //@}
384 
385  /** Returns true if this context has no parent. */
386  bool is_root_context() const { return parent_ == nullptr; }
387 
388  /** (Internal use only) Returns true if this context provides resources for
389  its own individual state variables or parameters. That means those variables
390  or parameters were declared by this context's corresponding System. Currently
391  only leaf systems may declare variables and parameters; diagram contexts
392  can use this method to check that invariant. */
394  return !(discrete_state_tickets_.empty() &&
395  abstract_state_tickets_.empty() &&
396  numeric_parameter_tickets_.empty() &&
397  abstract_parameter_tickets_.empty());
398  }
399 
400  /** (Internal use only) Clones a context but without copying any of its
401  internal pointers; the clone's pointers are set to null. */
402  // Structuring this as a static method allows DiagramContext to invoke this
403  // protected function on its children.
404  static std::unique_ptr<ContextBase> CloneWithoutPointers(
405  const ContextBase& source) {
406  return source.DoCloneWithoutPointers();
407  }
408 
409  /** (Internal use only) Given a new context `clone` containing an
410  identically-structured dependency graph as the one in `source`, creates a
411  mapping of all tracker memory addresses from `source` to `clone`. This must be
412  done for the whole Context tree because pointers can point outside of their
413  containing subcontext. */
414  // Structuring this as a static method allows DiagramContext to invoke this
415  // protected function on its children.
416  static void BuildTrackerPointerMap(
417  const ContextBase& source, const ContextBase& clone,
418  DependencyTracker::PointerMap* tracker_map);
419 
420  /** (Internal use only) Assuming `clone` is a recently-cloned Context that
421  has yet to have its internal pointers updated, sets those pointers now. The
422  given map is used to update tracker pointers. */
423  // Structuring this as a static method allows DiagramContext to invoke this
424  // protected function on its children.
425  static void FixContextPointers(
426  const ContextBase& source,
427  const DependencyTracker::PointerMap& tracker_map,
428  ContextBase* clone);
429 
430  /** (Internal use only) Applies the given caching-change notification method
431  to `context`, and propagates the notification to subcontexts if `context` is
432  a DiagramContext. Used, for example, to enable and disable the cache. The
433  supplied `context` is const so depends on the cache being mutable. */
434  // Structuring this as a static method allows DiagramContext to invoke this
435  // protected method on its children.
436  static void PropagateCachingChange(const ContextBase& context,
437  void (Cache::*caching_change)()) {
438  (context.get_mutable_cache().*caching_change)();
439  context.DoPropagateCachingChange(caching_change);
440  }
441 
442  /** (Internal use only) Applies the given bulk-change notification method
443  to the given `context`, and propagates the notification to subcontexts if this
444  is a DiagramContext. */
445  // Structuring this as a static method allows DiagramContext to invoke this
446  // protected method on its children.
447  static void PropagateBulkChange(
448  ContextBase* context, int64_t change_event,
449  void (ContextBase::*note_bulk_change)(int64_t change_event)) {
450  (context->*note_bulk_change)(change_event);
451  context->DoPropagateBulkChange(change_event, note_bulk_change);
452  }
453 
454  /** (Internal use only) This is a convenience method for invoking the
455  eponymous static method on `this` context (which occurs frequently). */
457  int64_t change_event,
458  void (ContextBase::*note_bulk_change)(int64_t change_event)) {
459  PropagateBulkChange(this, change_event, note_bulk_change);
460  }
461 
462  /** Declares that `parent` is the context of the enclosing Diagram.
463  Aborts if the parent has already been set or is null. */
464  // Use static method so DiagramContext can invoke this on behalf of a child.
465  // Output argument is listed first because it is serving as the 'this'
466  // pointer here.
467  static void set_parent(ContextBase* child, ContextBase* parent) {
468  DRAKE_DEMAND(child != nullptr);
469  DRAKE_DEMAND(parent != nullptr);
470  DRAKE_DEMAND(child->parent_ == nullptr);
471  child->parent_ = parent;
472  // This field is only used by the root context so set to an invalid
473  // value here.
474  child->current_change_event_ = -1;
475  }
476 
477  /** Derived classes must implement this so that it performs the complete
478  deep copy of the context, including all base class members but not fixing
479  up base class pointers. To do that, implement a protected copy constructor
480  that inherits from the base class copy constructor (which doesn't repair the
481  pointers), then implement DoCloneWithoutPointers() as
482  `return unique_ptr<ContextBase>(new DerivedType(*this));`. */
483  virtual std::unique_ptr<ContextBase> DoCloneWithoutPointers() const = 0;
484 
485  /** DiagramContext must implement this to invoke BuildTrackerPointerMap() on
486  each of its subcontexts. The default implementation does nothing which is
487  fine for a LeafContext. */
489  const ContextBase& clone,
490  DependencyTracker::PointerMap* tracker_map) const {
491  unused(clone, tracker_map);
492  }
493 
494  /** DiagramContext must implement this to invoke FixContextPointers() on
495  each of its subcontexts. The default implementation does nothing which is
496  fine for a LeafContext. */
498  const ContextBase& source,
499  const DependencyTracker::PointerMap& tracker_map) {
500  unused(source, tracker_map);
501  }
502 
503  /** DiagramContext must implement this to invoke a caching behavior change on
504  each of its subcontexts. The default implementation does nothing which is
505  fine for a LeafContext. */
506  virtual void DoPropagateCachingChange(void (Cache::*caching_change)()) const {
507  unused(caching_change);
508  }
509 
510  /** DiagramContext must implement this to invoke PropagateBulkChange()
511  on its subcontexts, passing along the indicated method that specifies the
512  particular bulk change (e.g. whole state, all parameters, all discrete state
513  variables, etc.). The default implementation does nothing which is fine for
514  a LeafContext. */
515  virtual void DoPropagateBulkChange(
516  int64_t change_event,
517  void (ContextBase::*note_bulk_change)(int64_t change_event)) {
518  unused(change_event, note_bulk_change);
519  }
520 
521  private:
522  friend class detail::SystemBaseContextBaseAttorney;
523 
524  // Returns the parent Context or `nullptr` if this is the root Context.
525  const ContextBase* get_parent_base() const { return parent_; }
526 
527  // Records the name of the system whose context this is.
528  void set_system_name(const std::string& name) { system_name_ = name; }
529 
530  // Fixes the input port at `index` to the internal value source `port_value`.
531  // If the port wasn't previously fixed, assigns a ticket and tracker for the
532  // `port_value`, then subscribes the input port to the source's tracker.
533  // If the port was already fixed, we just use the existing tracker and
534  // subscription but replace the value. Notifies the port's downstream
535  // subscribers that the value has changed. Aborts if `index` is out of range,
536  // or the given `port_value` is null or already belongs to a context.
537  void SetFixedInputPortValue(
538  InputPortIndex index,
539  std::unique_ptr<FixedInputPortValue> port_value);
540 
541  // Fills in the dependency graph with the built-in trackers that are common
542  // to every Context (and every System).
543  void CreateBuiltInTrackers();
544 
545  // We record tickets so we can reconstruct the dependency graph when cloning
546  // or transmogrifying a Context without a System present.
547 
548  // Index by InputPortIndex.
549  std::vector<DependencyTicket> input_port_tickets_;
550  // Index by OutputPortIndex.
551  std::vector<DependencyTicket> output_port_tickets_;
552  // Index by DiscreteStateIndex.
553  std::vector<DependencyTicket> discrete_state_tickets_;
554  // Index by AbstractStateIndex.
555  std::vector<DependencyTicket> abstract_state_tickets_;
556  // Index by NumericParameterIndex.
557  std::vector<DependencyTicket> numeric_parameter_tickets_;
558  // Index by AbstractParameterIndex.
559  std::vector<DependencyTicket> abstract_parameter_tickets_;
560 
561  // For each input port, the fixed value or null if the port is connected to
562  // something else (in which case we need System help to get the value).
563  // Semantically, these are identical to Parameters.
564  // Each non-null FixedInputPortValue has a ticket and associated
565  // tracker.
566  // Index with InputPortIndex.
567  std::vector<copyable_unique_ptr<FixedInputPortValue>>
568  input_port_values_;
569 
570  // The cache of pre-computed values owned by this subcontext.
571  mutable Cache cache_;
572 
573  // This is the dependency graph for values within this subcontext.
574  DependencyGraph graph_;
575 
576  // This is used only when this subcontext is serving as the root of a context
577  // tree, in which case it will be initialized to zero as shown. In any
578  // non-root context, it will be reset to -1 when the parent pointer is
579  // assigned and must never change from that value.
580  // Note that it does *not* get reset when copied.
581  int64_t current_change_event_{0};
582 
583  // The Context of the enclosing Diagram. Null/invalid when this is the root
584  // context.
586 
587  // Name of the subsystem whose subcontext this is.
588  std::string system_name_;
589 
590  // Used to validate that System-derived classes didn't forget to invoke the
591  // SystemBase method that properly sets up the ContextBase.
592  bool is_context_base_initialized_{false};
593 };
594 
595 #ifndef DRAKE_DOXYGEN_CXX
596 class SystemBase;
597 namespace detail {
598 
599 // This is an attorney-client pattern class providing SystemBase with access to
600 // certain specific ContextBase private methods, and nothing else.
601 class SystemBaseContextBaseAttorney {
602  public:
603  DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN(SystemBaseContextBaseAttorney)
604  SystemBaseContextBaseAttorney() = delete;
605 
606  private:
607  friend class drake::systems::SystemBase;
608 
609  static void set_system_name(ContextBase* context, const std::string& name) {
610  DRAKE_DEMAND(context != nullptr);
611  context->set_system_name(name);
612  }
613  static const ContextBase* get_parent_base(const ContextBase& context) {
614  return context.get_parent_base();
615  }
616 
617  static void AddInputPort(ContextBase* context, InputPortIndex expected_index,
618  DependencyTicket ticket) {
619  DRAKE_DEMAND(context != nullptr);
620  context->AddInputPort(expected_index, ticket);
621  }
622 
623  static void AddOutputPort(
624  ContextBase* context, OutputPortIndex expected_index,
625  DependencyTicket ticket,
626  const internal::OutputPortPrerequisite& prerequisite) {
627  DRAKE_DEMAND(context != nullptr);
628  context->AddOutputPort(expected_index, ticket, prerequisite);
629  }
630 
631  // Provide SystemBase mutable access to the ticket lists.
632  static void AddDiscreteStateTicket(ContextBase* context,
633  DependencyTicket ticket) {
634  DRAKE_DEMAND(context != nullptr);
635  context->AddDiscreteStateTicket(ticket);
636  }
637 
638  static void AddAbstractStateTicket(ContextBase* context,
639  DependencyTicket ticket) {
640  DRAKE_DEMAND(context != nullptr);
641  context->AddAbstractStateTicket(ticket);
642  }
643 
644  static void AddNumericParameterTicket(ContextBase* context,
645  DependencyTicket ticket) {
646  DRAKE_DEMAND(context != nullptr);
647  context->AddNumericParameterTicket(ticket);
648  }
649 
650  static void AddAbstractParameterTicket(ContextBase* context,
651  DependencyTicket ticket) {
652  DRAKE_DEMAND(context != nullptr);
653  context->AddAbstractParameterTicket(ticket);
654  }
655 
656  static bool is_context_base_initialized(const ContextBase& context) {
657  return context.is_context_base_initialized_;
658  }
659 
660  // SystemBase should invoke this when ContextBase has been successfully
661  // initialized.
662  static void mark_context_base_initialized(ContextBase* context) {
663  DRAKE_DEMAND(context);
664  DRAKE_DEMAND(!context->is_context_base_initialized_);
665  context->is_context_base_initialized_ = true;
666  }
667 };
668 
669 } // namespace detail
670 #endif
671 
672 } // namespace systems
673 } // namespace drake
Manages value interdependencies for a particular value or set of values in a Context.
Definition: dependency_tracker.h:134
virtual void DoPropagateBulkChange(int64_t change_event, void(ContextBase::*note_bulk_change)(int64_t change_event))
DiagramContext must implement this to invoke PropagateBulkChange() on its subcontexts, passing along the indicated method that specifies the particular bulk change (e.g.
Definition: context_base.h:515
virtual std::unique_ptr< ContextBase > DoCloneWithoutPointers() const =0
Derived classes must implement this so that it performs the complete deep copy of the context...
Type wrapper that performs value-initialization on copy construction or assignment.
Definition: reset_on_copy.h:81
double value
Definition: wrap_test_util_py.cc:12
bool owns_any_variables_or_parameters() const
(Internal use only) Returns true if this context provides resources for its own individual state vari...
Definition: context_base.h:393
void DisableCaching() const
(Debugging) Disables caching recursively for this context and all its subcontexts.
Definition: context_base.h:63
Definition: bullet_model.cc:22
const DependencyTracker & get_tracker(DependencyTicket ticket) const
Returns a const reference to a DependencyTracker in this subcontext.
Definition: context_base.h:126
void EnableCaching() const
(Debugging) Re-enables caching recursively for this context and all its subcontexts.
Definition: context_base.h:76
int get_num_output_ports() const
Returns the number of output ports represented in this context.
Definition: context_base.h:155
ContextBase()
Default constructor creates an empty ContextBase but initializes all the built-in dependency trackers...
Definition: context_base.h:231
const FixedInputPortValue * MaybeGetFixedInputPortValue(int index) const
For input port index, returns a const FixedInputPortValue if the port is fixed, otherwise nullptr...
Definition: context_base.h:196
void NoteAllAbstractParametersChanged(int64_t change_event)
Notifies each local abstract parameter tracker that the value of the parameter it manages may have ch...
Definition: context_base.h:379
STL namespace.
void AddOutputPort(OutputPortIndex expected_index, DependencyTicket ticket, const internal::OutputPortPrerequisite &prerequisite)
Adds the next output port.
Definition: context_base.cc:63
static void set_parent(ContextBase *child, ContextBase *parent)
Declares that parent is the context of the enclosing Diagram.
Definition: context_base.h:467
Represents the portion of the complete dependency graph that is a subgraph centered on the owning sub...
Definition: dependency_tracker.h:442
static std::unique_ptr< ContextBase > CloneWithoutPointers(const ContextBase &source)
(Internal use only) Clones a context but without copying any of its internal pointers; the clone&#39;s po...
Definition: context_base.h:404
DependencyTracker & get_mutable_tracker(DependencyTicket ticket)
Returns a mutable reference to a DependencyTracker in this subcontext.
Definition: context_base.h:132
const DependencyGraph & get_dependency_graph() const
Returns a const reference to the collection of value trackers within this subcontext.
Definition: context_base.h:139
void AddInputPort(InputPortIndex expected_index, DependencyTicket ticket)
Adds the next input port.
Definition: context_base.cc:49
void NoteTimeChanged(int64_t change_event)
Notifies the local time tracker that time may have changed.
Definition: context_base.h:293
void NoteAllZChanged(int64_t change_event)
Notifies the local z tracker that the z&#39;s may have changed.
Definition: context_base.h:335
void NoteAllAbstractStateChanged(int64_t change_event)
Notifies each local abstract state variable tracker that the value of the abstract state variable it ...
Definition: context_base.h:353
Stores all the CacheEntryValue objects owned by a particular Context, organized to allow fast access ...
Definition: cache.h:592
Provides non-templatized Context functionality shared by the templatized derived classes.
Definition: context_base.h:38
std::unique_ptr< KinematicsCache< double > > cache_
Definition: differential_inverse_kinematics_test.cc:141
#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:37
bool is_root_context() const
Returns true if this context has no parent.
Definition: context_base.h:386
Cache & get_mutable_cache() const
(Advanced) Returns a mutable reference to this subcontext&#39;s cache.
Definition: context_base.h:119
Declares CacheEntryValue and Cache, which is the container for cache entry values.
#define DRAKE_DEMAND(condition)
Evaluates condition and iff the value is false will trigger an assertion failure with a message showi...
Definition: drake_assert.h:45
virtual void DoPropagateFixContextPointers(const ContextBase &source, const DependencyTracker::PointerMap &tracker_map)
DiagramContext must implement this to invoke FixContextPointers() on each of its subcontexts.
Definition: context_base.h:497
void SetAllCacheEntriesOutOfDate() const
(Debugging) Marks all cache entries out of date, recursively for this context and all its subcontexts...
Definition: context_base.h:88
void NoteAllParametersChanged(int64_t change_event)
Notifies the local numeric and abstract parameter trackers that each of them may have changed...
Definition: context_base.h:361
void AddDiscreteStateTicket(DependencyTicket ticket)
Adds a ticket to the list of discrete state tickets.
Definition: context_base.h:260
void NoteAllNumericParametersChanged(int64_t change_event)
Notifies each local numeric parameter tracker that the value of the parameter it manages may have cha...
Definition: context_base.h:370
DependencyGraph & get_mutable_dependency_graph()
Returns a mutable reference to the dependency graph.
Definition: context_base.h:144
DependencyTicket input_port_ticket(InputPortIndex port_num)
Returns the dependency ticket associated with a particular input port.
Definition: context_base.h:160
Provides non-templatized functionality shared by the templatized System classes.
Definition: system_base.h:29
void PropagateBulkChange(int64_t change_event, void(ContextBase::*note_bulk_change)(int64_t change_event))
(Internal use only) This is a convenience method for invoking the eponymous static method on this con...
Definition: context_base.h:456
static void PropagateBulkChange(ContextBase *context, int64_t change_event, void(ContextBase::*note_bulk_change)(int64_t change_event))
(Internal use only) Applies the given bulk-change notification method to the given context...
Definition: context_base.h:447
std::unordered_map< const DependencyTracker *, const DependencyTracker * > PointerMap
(Internal use only)
Definition: dependency_tracker.h:140
void AddAbstractStateTicket(DependencyTicket ticket)
Adds a ticket to the list of abstract state tickets.
Definition: context_base.h:265
virtual void DoPropagateCachingChange(void(Cache::*caching_change)()) const
DiagramContext must implement this to invoke a caching behavior change on each of its subcontexts...
Definition: context_base.h:506
A fully type-erased container class.
Definition: value.h:101
int get_num_input_ports() const
Returns the number of input ports in this context.
Definition: context_base.h:149
void NoteAllDiscreteStateChanged(int64_t change_event)
Notifies each local discrete state group tracker that the value of the discrete state group it manage...
Definition: context_base.h:344
FixedInputPortValue & FixInputPort(int index, const AbstractValue &value)
Same as above method but the value is passed by const reference instead of by unique_ptr.
Definition: context_base.h:189
FixedInputPortValue * MaybeGetMutableFixedInputPortValue(int index)
For input port index, returns a mutable FixedInputPortValue if the port is fixed, otherwise nullptr...
Definition: context_base.h:204
void AddAbstractParameterTicket(DependencyTicket ticket)
Adds a ticket to the list of abstract parameter tickets.
Definition: context_base.h:275
static void PropagateCachingChange(const ContextBase &context, void(Cache::*caching_change)())
(Internal use only) Applies the given caching-change notification method to context, and propagates the notification to subcontexts if context is a DiagramContext.
Definition: context_base.h:436
void NoteAllStateChanged(int64_t change_event)
Notifies the local continuous, discrete, and abstract state trackers that each of them may have chang...
Definition: context_base.h:308
void NoteAllContinuousStateChanged(int64_t change_event)
Notifies the local q, v, and z trackers that each of them may have changed, likely because someone ha...
Definition: context_base.h:316
Declares DependencyTracker and DependencyGraph which is the container for trackers.
void NoteAllQChanged(int64_t change_event)
Notifies the local q tracker that the q&#39;s may have changed.
Definition: context_base.h:323
TypeSafeIndex< class DependencyTag > DependencyTicket
Identifies a particular source value or computation for purposes of declaring and managing dependenci...
Definition: framework_common.h:26
void DisableCaching()
(Advanced) Disables caching for all the entries in this Cache.
Definition: cache.cc:112
void EnableCaching()
(Advanced) Re-enables caching for all entries in this Cache if any were previously disabled...
Definition: cache.cc:118
int64_t start_new_change_event()
(Internal use only) Returns the next change event serial number that is unique for this entire Contex...
Definition: context_base.h:212
virtual std::unique_ptr< AbstractValue > Clone() const =0
Returns a copy of this AbstractValue.
A FixedInputPortValue encapsulates a vector or abstract value for use as an internal value source for...
Definition: fixed_input_port_value.h:35
void NoteAccuracyChanged(int64_t change_event)
Notifies the local accuracy tracker that the accuracy setting may have changed.
Definition: context_base.h:300
#define DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN(Classname)
DRAKE_NO_COPY_NO_MOVE_NO_ASSIGN deletes the special member functions for copy-construction, copy-assignment, move-construction, and move-assignment.
Definition: drake_copyable.h:33
void NoteAllVChanged(int64_t change_event)
Notifies the local v tracker that the v&#39;s may have changed.
Definition: context_base.h:329
virtual void DoPropagateBuildTrackerPointerMap(const ContextBase &clone, DependencyTracker::PointerMap *tracker_map) const
DiagramContext must implement this to invoke BuildTrackerPointerMap() on each of its subcontexts...
Definition: context_base.h:488
DependencyTicket output_port_ticket(OutputPortIndex port_num)
Returns the dependency ticket associated with a particular output port.
Definition: context_base.h:166
std::string name
Definition: geometry_base_test.cc:343
void SetAllEntriesOutOfDate()
(Advanced) Mark every entry in this cache as "out of date".
Definition: cache.cc:123
const Cache & get_cache() const
Returns a const reference to this subcontext&#39;s cache.
Definition: context_base.h:107
const std::string & GetSystemName() const final
Returns the local name of the subsystem for which this is the Context.
Definition: context_base.h:96
void AddNumericParameterTicket(DependencyTicket ticket)
Adds a ticket to the list of numeric parameter tickets.
Definition: context_base.h:270
void unused(const Args &...)
Documents the argument(s) as unused, placating GCC&#39;s -Wunused-parameter warning.
Definition: unused.h:51