137 lines
4.1 KiB
ReStructuredText
137 lines
4.1 KiB
ReStructuredText
Scriptable Verification
|
|
=======================
|
|
|
|
NavalToolbox includes a powerful scripting engine based on `Rhai <https://rhai.rs>`_ that allows you to define and verify custom stability criteria without recompiling the library.
|
|
|
|
Overview
|
|
--------
|
|
|
|
The verification process involves three steps:
|
|
|
|
1. **Calculate Stability**: Perform standard stability analysis (GZ curve, etc.).
|
|
2. **Create Context**: Wrap the result into a ``CriteriaContext``.
|
|
3. **Run Script**: Execute a Rhai script using ``ScriptEngine``.
|
|
|
|
Basic Example
|
|
-------------
|
|
|
|
.. code-block:: python
|
|
|
|
from navaltoolbox import CriteriaContext, ScriptEngine, StabilityCalculator
|
|
|
|
# 1. Calculate stability
|
|
calc = StabilityCalculator(vessel)
|
|
result = calc.complete_stability(...)
|
|
|
|
# 2. Create context
|
|
ctx = CriteriaContext.from_result(result, "MV Example", "Departure")
|
|
|
|
# 3. Run script
|
|
engine = ScriptEngine()
|
|
criteria = engine.run_script_file("rules/is_code_2008_general.rhai", ctx)
|
|
|
|
# Check results
|
|
if criteria.overall_pass:
|
|
print("Vessel Compliant")
|
|
else:
|
|
print(f"Failed {criteria.fail_count} criteria")
|
|
|
|
for c in criteria.criteria:
|
|
print(f"{c.name}: {c.status} (Actual: {c.actual_value} {c.unit})")
|
|
|
|
Writing Custom Scripts
|
|
----------------------
|
|
|
|
Scripts are written in Rhai. You have access to the ``ctx`` object which provides helper methods.
|
|
|
|
.. code-block:: rust
|
|
|
|
// Custom criterion script
|
|
|
|
fn check(ctx) {
|
|
// 1. Get data
|
|
let area_30 = ctx.area_under_curve(0.0, 30.0);
|
|
let gz_30 = ctx.gz_at_angle(30.0);
|
|
|
|
let results = [];
|
|
|
|
// 2. Define criteria
|
|
// The criterion() function optionally takes a 6th argument for the comparison operator.
|
|
// Supported operators: "<=", ">=", "<", ">", "=="
|
|
// If omitted, it defaults to ">=" (actual >= required).
|
|
|
|
results.push(criterion(
|
|
"Area 0-30",
|
|
"Minimum area under GZ curve up to 30 deg",
|
|
0.055, // Required
|
|
area_30, // Actual
|
|
"m.rad" // Unit
|
|
// Implicitly uses ">="
|
|
));
|
|
|
|
results.push(criterion(
|
|
"GZ at 30",
|
|
"Minimum GZ at 30 deg",
|
|
0.20,
|
|
gz_30,
|
|
"m",
|
|
">=" // Explicit operator
|
|
));
|
|
|
|
// Example for a maximum allowed value (e.g., wind heel angle)
|
|
// results.push(criterion("Equilibrium", "Steady wind heel <= 16 deg", 16.0, heel, "deg", "<="));
|
|
|
|
// 3. Define Plot (Optional)
|
|
let plot = #{
|
|
id: "main_plot",
|
|
title: "GZ Curve",
|
|
x_label: "Heel (deg)",
|
|
y_label: "GZ (m)",
|
|
elements: [
|
|
#{
|
|
type: "Curve",
|
|
name: "GZ",
|
|
x: ctx.get_heels(),
|
|
y: ctx.get_gz_values(),
|
|
color: "blue"
|
|
}
|
|
]
|
|
};
|
|
|
|
// Link criteria to plot
|
|
for r in results { r.plot_id = "main_plot"; }
|
|
|
|
// 4. Return result map
|
|
let fail_count = 0;
|
|
for r in results { if r.status == "FAIL" { fail_count += 1; } }
|
|
|
|
#{
|
|
regulation_name: "My Custom Rules",
|
|
regulation_reference: "CUSTOM-01",
|
|
vessel_name: ctx.get_vessel_name(),
|
|
loading_condition: ctx.get_loading_condition(),
|
|
displacement: ctx.get_displacement(),
|
|
overall_pass: fail_count == 0,
|
|
criteria: results,
|
|
plots: [plot],
|
|
notes: ""
|
|
}
|
|
}
|
|
|
|
Plotting Results
|
|
----------------
|
|
|
|
You can visualize the verification results using the built-in plotting utility (requires Matplotlib).
|
|
|
|
.. code-block:: python
|
|
|
|
from navaltoolbox import plotting
|
|
|
|
# Display interactively
|
|
plotting.plot_criteria_result(criteria)
|
|
|
|
# Save to file
|
|
plotting.plot_criteria_result(criteria, show=False, save_to="report.png")
|
|
|
|
This generates a graph showing the GZ curve along with visual indications of the criteria (threshold lines, areas, etc.).
|