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 half-open 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... | |
boolean< 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... | |
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 |
boolean<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.