Drake

Class that stores a function that is able to help determine the time and state at which a step of the initial value problem integration of a System should end, which may be done for any number of purposes, including publishing or state reinitialization (i.e., event handling).
System authors declare witness functions through LeafSystem::MakeWitnessFunction().
For the ensuing discussion, consider two times (t₀
and t₁ > t₀
) and states corresponding to those times (x(t₀)
and x(t₁)
). A witness function, w(t, x)
, "triggers" only when it crosses zero at a time t*
where t₀ < t* ≤ t₁
. Note the halfopen interval. For an example of a witness function, consider the "signed distance" (i.e., Euclidean distance when bodies are disjoint and minimum translational distance when bodies intersect) between two rigid bodies; this witness function can be used to determine both the time of impact for rigid bodies and their states at that time of impact.
Precision in the definition of the witness function is necessary, because we want the witness function to trigger only once if, for example, w(t₀, x(t₀)) ≠ 0
, w(t₁, x(t₁)) = 0
, and w(t₂, x(t₂)) ≠ 0
, for some t₂ > t₁. In other words, if the witness function is evaluated over the intervals [t₀, t₁] and [t₁, t₂], meaning that the zero occurs precisely at an interval endpoint, the witness function should trigger once. Similarly, the witness function should trigger exactly once if w(t₀, x(t₀)) ≠ 0
, w(t*, x(t*)) = 0
, and w(t₁, x(t₁)) = 0
, for t* ∈ (t₀, t₁)
. We can define the trigger condition formally over interval [t₀, t₁]
using the function:
T(w, t₀, x(t₀), t₁) = 1 if w(t₀, x(t₀)) ≠ 0 and w(t₀, x(t₀))⋅w(t₁, x(t₁)) ≤ 0 0 if w(t₀, x(t₀)) = 0 or w(t₀, x(t₀))⋅w(t₁, x(t₁)) > 0
We wish for the witness function to trigger if the trigger function evaluates to one. The trigger function can be further modified, if desired, to incorporate the constraint that the witness function should trigger only when crossing from positive values to negative values, or vice versa.
A good witness function should not cross zero repeatedly over a small interval of time (relative to the maximum designated integration step size) or over small changes in state; when a witness function has been "bracketed" over an interval of time (i.e., it changes sign), that witness function will ideally cross zero only once in that interval.
A witness function trigger time is isolated only to a small interval of time (as described in Simulator). The disadvantage of this scheme is that it always requires the length of the interval to be reduced to the requisite length and that each function evaluation (which requires numerical integration) is extraordinarily expensive. If, for example, the (slow) bisection algorithm were used to isolate the time interval, the number of integrations necessary to cut the interval from a length of ℓ to a length of ε will be log₂(ℓ / ε). Bisection is just one of several possible algorithms for isolating the time interval, though it's a reliable choice and always converges linearly.
#include <drake/systems/framework/witness_function.h>
Public Types  
using  CalcCallback = std::function< T(const Context< T > &)> 
Signature of a function suitable for calculating a value of a particular witness function. More...  
Public Member Functions  
const std::string &  description () const 
Gets the description of this witness function (used primarily for logging and debugging). More...  
WitnessFunctionDirection  direction_type () const 
Gets the direction(s) under which this witness function triggers. More...  
T  CalcWitnessValue (const Context< T > &context) const 
Evaluates the witness function at the given context. More...  
const System< T > &  get_system () const 
Gets a reference to the System used by this witness function. More...  
decltype(T()< T())  should_trigger (const T &w0, const T &wf) const 
Checks whether the witness function should trigger using given values at w0 and wf. More...  
template<class EventType >  
void  set_event (std::unique_ptr< EventType > e) 
Sets the event that will be dispatched when the witness function triggers. More...  
const Event< T > *  get_event () const 
Gets the event that will be dispatched when the witness function triggers. More...  
Event< T > *  get_mutable_event () 
Gets a mutable pointer to the event that will occur when the witness function triggers. More...  
Does not allow copy, move, or assignment  
WitnessFunction (const WitnessFunction &)=delete  
WitnessFunction &  operator= (const WitnessFunction &)=delete 
WitnessFunction (WitnessFunction &&)=delete  
WitnessFunction &  operator= (WitnessFunction &&)=delete 
using CalcCallback = std::function<T(const Context<T>&)> 
Signature of a function suitable for calculating a value of a particular witness function.

delete 

delete 
T CalcWitnessValue  (  const Context< T > &  context  )  const 
Evaluates the witness function at the given context.
const std::string& description  (  )  const 
Gets the description of this witness function (used primarily for logging and debugging).
WitnessFunctionDirection direction_type  (  )  const 
Gets the direction(s) under which this witness function triggers.
const Event<T>* get_event  (  )  const 
Gets the event that will be dispatched when the witness function triggers.
A null pointer indicates that no event will be dispatched.
Event<T>* get_mutable_event  (  ) 
Gets a mutable pointer to the event that will occur when the witness function triggers.

delete 

delete 
void set_event  (  std::unique_ptr< EventType >  e  ) 
Sets the event that will be dispatched when the witness function triggers.
If e
is null, no event will be dispatched.
decltype(T() < T()) should_trigger  (  const T &  w0, 
const T &  wf  
)  const 
Checks whether the witness function should trigger using given values at w0 and wf.
Note that this function is not specific to a particular witness function.