Model - Lua Model/MCL

Synposis

Run models written in Lua using the Lua Model Library and operated via the built-in Lua MCL (Model Compatibility Library).

Lua Model using the Lua Model Library and Lua MCL Interface

function model_step()
    model:log_notice("model_step() @ %f", model:model_time())

    -- Increment the counter signal.
    local counter = model.sv["signal"].scalar[SIG_COUNTER]
    counter = counter + 1
    model.sv["signal"].scalar[SIG_COUNTER] = counter

    -- Indicate success.
    return 0
end

Model

Structure

examples/lua/model
    └── sim
        ├── data
        │    └── simulation.yml
        │    └── signalgroup.yml        <-- Simulation signals.
        └── model
            └── lua
                └── data
                    └── model.lua       <-- Lua Model.

Lua MCL Interface

model_create

model_create()
: returns  int 0 indicates success

The model_create() function is called by the ModelC Runtime at the start of a simulation and gives the Lua Model an opportunity to index signals, set initial values and do other setup tasks.

model_step

model_step()
: returns  int 0 indicates success

The model_step() function is called by the ModelC Runtime on each simulation step. The Lua Model can calculate new signal values according to its own algorithm and complete other tasks. The ModelC Runtime will make the new signal values available to the rest of the simulation when the step completes.

model_destroy

model_destroy()
: returns  int 0 indicates success

The model_destroy() function is called by the ModelC Runtime at the end of a simulation and gives the Lua Model an opportunity to release any allocated resources and complete other tasks before the simulation exits.

Lua Model Library

Model API

model:version

model:version()
: returns  string

Returns the version string of the ModelC Runtime being used by the Lua Model Library.

model:step_size

model:step_size()
 : returns  number

Returns the configured step size of the current simulation environment.

model:model_time

model:model_time()
 : returns  number

Returns the current model time of this model (in the current simulation environment).

Signal API

model.sv[]:find

model.sv[channel_name]:find(signal_name)
 : returns number
 : returns nil when signal not found
  • channel_name: (string) the name of the signal vector where the signal is located. The channel_name should be the alias used by the Model Instance (representing this model) in the Simulation Stack or DSE Script.
  • signal_name: (string) the name of the signal to find.

Search for a signal in a specific signal vector and return the index of that signal: The index can be used in the sv.signal[] and sv.scalar[] arrays.

Hint: Use this index to achieve the most performant access to signals.

model.sv[]:annotation

model.sv[channel_name]:annotation(signal_name, annotation_path)
 : returns string the annotation value
 : returns nil if the annotation was not located
  • channel_name: (string) the name of the signal vector where the signal is located. The channel_name should be the alias used by the Model Instance (representing this model) in the Simulation Stack or DSE Script.
  • signal_name: (string) the name of the signal.
  • annotation_path: (string) the path/name of the annotation to locate.

Read a signal annotation from the given annotation path. These annotations are load from the underlying SignalGroup YAML file (associated schema).

model.sv[]:group_annotation

model.sv[channel_name]:group_annotation(annotation_path)
 : returns string the annotation value
 : returns nil if the annotation was not located
  • channel_name: (string) the name of the signal vector where the signal is located. The channel_name should be the alias used by the Model Instance (representing this model) in the Simulation Stack or DSE Script.
  • annotation_path: (string) the path/name of the annotation to locate.

Read a signal group annotation from the given annotation path. These annotations are load from the underlying SignalGroup YAML file (associated schema).

model.sv[].signal[]

model.sv[channel_name].signal[signal_name]
model.sv[channel_name].signal[index]
 : returns string the signal name
 : returns nil if the signal was not located in the array
  • channel_name: (string) the name of the signal vector where the signal is located. The channel_name should be the alias used by the Model Instance (representing this model) in the Simulation Stack or DSE Script.
  • signal_name: (string) the name of the signal to index in the signal[] array.
  • index: (int) direct index into the signal[] array. See model.sv[]:find.

The signal array represents the name of signals in the simulation, organised into channels by channel_name. Each value in the signal array has a corresponding value in the scalar array (i.e. at the same index).

model.sv[].scalar[]

model.sv[channel_name].scalar[signal_name]
model.sv[channel_name].scalar[index]
 : returns number the value of the signal
 : returns nil if the signal was not located in the array
  • channel_name: (string) the name of the signal vector where the signal is located. The channel_name should be the alias used by the Model Instance (representing this model) in the Simulation Stack or DSE Script.
  • signal_name: (string) the name of the signal to index in the scalar[] array.
  • index: (int) direct index into the scalar[] array. See model.sv[]:find.

The scalar array represents signal values in the simulation and can be modified by a Lua Model. Use this array to access and modify scalar signal values. Each value in the scalar array has a corresponding value in the signal array (i.e. at the same index).

Logging API

model:log_notice

model.log_notice(format, ...)
  • format: (string) a Lua format string.
  • : (any) a variable number of arguments to insert into the format string.

Produces a Notice Log via the ModelC Runtime logging subsystem.

model:log_info

model.log_info(format, ...)
  • format: (string) a Lua format string.
  • : (any) a variable number of arguments to insert into the format string.

Produces a Info Log via the ModelC Runtime logging subsystem.

model:log_debug

model.log_debug(format, ...)
  • format: (string) a Lua format string.
  • : (any) a variable number of arguments to insert into the format string.

Produces a Debug Log via the ModelC Runtime logging subsystem.

model:log_error

model.log_error(format, ...)
  • format: (string) a Lua format string.
  • : (any) a variable number of arguments to insert into the format string.

Produces a Error Log via the ModelC Runtime logging subsystem.

Examples

Lua Model

SIG_COUNTER = 1
signal_map = {
    [SIG_COUNTER] = "counter",
}
signals = {}


function index_signals()
    for idx, signal in pairs(signal_map) do
        local sv_idx = model.sv["signal"]:find(signal)
        signals[idx] = sv_idx
        model:log_notice("signal indexed: [%d]%s -> sv[\"signal\"].scalar[%d]", idx, signal, sv_idx)
    end
end

function set_initial_values()
    for idx, signal in pairs(signal_map) do
        local annotation = model.sv["signal"]:annotation(signal, "initial_value")
        local value = tonumber(annotation)
        if value ~= nil then
            model.sv["signal"].scalar[signals[idx]] = value
        end
    end
end

function print_signal_values()
    for idx, signal in pairs(signal_map) do
        model:log_notice("signal value: [%d]%s = %f", idx, signal, model.sv["signal"].scalar[signals[idx]])
    end
end


function model_create()
    model:log_notice("model_create()")
    model:log_notice("  step_size: %f", model:step_size())

    -- Debugging info.
    model:log_debug(tostring(model))

    -- Index signals used by this model.
    index_signals()

    -- Signal initial values.
    set_initial_values()
    print_signal_values()

    -- Indicate success.
    return 0
end

function model_step()
    model:log_notice("model_step() @ %f", model:model_time())

    -- Increment the counter signal.
    model.sv["signal"].scalar[signals[SIG_COUNTER]] = model.sv["signal"].scalar[signals[SIG_COUNTER]] + 1
    print_signal_values()

    -- Indicate success.
    return 0
end

function model_destroy()
    model:log_notice("model_destroy()")

    -- Indicate success.
    return 0
end

DSE Script

simulation
channel physical

uses
dse.modelc https://github.com/boschglobal/dse.modelc v2.1.32

model lua_inst dse.modelc.lua path=data/model.lua
channel physical signal
file lua_model.lua data/model.lua

Simulation Stack

---
kind: Stack
metadata:
  name: lua_model
spec:
  connection:
    transport:
      redispubsub:
        uri: redis://localhost:6379
        timeout: 60
  models:
    - name: simbus
      model:
        name: simbus
      channels:
        - name: physical
          expectedModelCount: 1
    - name: lua_inst
      uid: 42
      runtime:
        mcl: lua
        files:
          - data/model.lua
      channels:
        - name: physical
          alias: signal
          selectors:
            signal: signal
---
kind: SignalGroup
metadata:
  name: signal
  labels:
    signal: signal
  annotations:
    vector_name: signal
spec:
  signals:
    - signal: counter
      annotations:
        initial_value: 23