Constraints
Constraint procedures give you the power to write arbitrarily complex rules that can be checked against events, activities, and resources associated with models and/or plans.
To create a constraint procedure, you simply need to create a simple java record with a single method that takes Plan
and SimulationResults
objects as arguments and returns a Violations
timeline. Violations are a new type of timeline specific to constraints, that store Violation
objects. You won't usually need to perform additional operations after creating a Violations
timeline; usually you'll just return it. They can be created with some provided static constructor functions. For example:
@ConstraintProcedure
public class BatteryAboveZero implements Constraint {
@Override
public Violations run( Plan plan, SimulationResults simResults) {
return Violations.inside(
plan.resource("/battery_soc", Real.deserializer()).lessThan(0).highlightTrue()
);
}
}
Constraint Basics
When building a constraint procedure, the primary goal is to find windows of time within the plan that violate a constraint and then turn those windows into a list of
constraints to be reported and visualized by Aerie. A few of the Aerie Timelines objects will come in handy as you manipulate information available within the Plan
and SimulationResults
objects:
- The
Windows
object provides a number of logical operations (e.g. union, intersection) that you can perform against sets of windows in order to converge on the set of violation windows you want to return. These objects are most useful when performing logic on activities. - The
Interval
object has similar functionality toWindows
, but is often useful when you want to compare or perform operations one interval at a time - The
Booleans
object provides comparison operations (e.g. and, or) on other profiles, which is great when trying to combine resource constraints together to form a composite constraint (e.g. resource A is greater than X, but less than Y)
SimResults.instance("nameOfActType")
and SimResults.resource("nameOfResource", <deserializer>)
are the simplest way to get simulated activities and resource values from your plan to manipulate. These methods had a number of helper methods you can use to do further filtering or conversion to Windows (.highlight()
), a List of Intervals (.collect()
), or Boolean timelines (e.g. .greaterThan()
).
For more examples of the use of these objects and methods, see the Procedural Constraints Examples page.
Violation Messages
The Violation
class contains a message
field, which will display to the user in the UI. It is null
by default,
but you have a few ways to change it.
If you're creating a Violations
timeline, you can call violations.withDefaultMessage(message)
, which sets the message
for those in the result that don't already have one. You can also set the message on a per-Violation
basis by constructing each Violation
object manually.