Lua Scripting
Introduction
FOME allows to extend and customize firmware functionality and behavior by providing a Lua script interpreter. Various sensors, signals, and state are provided for reading and manipulating , allowing to tailor a control strategy to fit the applications needs.
This page documents the most up-to-date version of FOME's Lua scripting support: not all interfaces are supported in earlier versions.
Overview
FOME provides Lua interface with a number of functions and types to interface with the firmware and to discern and manipulate its state and configuration. At a high level, the interface comprises these categories:
- A small utility library, including timers, and user-defined lookups; see the Utilities reference.
- General input and output; see the Input and Output reference.
- Firmware sensors and control; see the Sensors reference.
- CAN bus communication; see the CAN bus reference.
- SENT protocol communication; see the SENT protocol reference.
- Firmware state and configuration; see the Firmware ... TODO reference.
For examples see the files in FOME's lua/examples/
directory.
For a basic introduction see this wiki section.
Conventions
- The Lua interpreter will trigger an error if there is a mistake in the program: check the FOME Console to see errors and script output.
- Unless otherwise mentioned, all
index
parameters start with the first element at index 0.
Writing Your Script
The entire Lua script is read and validated at startup, then a global script function named onTick
is invoked periodically by the firmware.
Here is a simple script to illustrate this behavior:
print('Hello FOME via Lua!')
function onTick()
print('FOME called onTick()')
end
User-Defined Lookup Tables and Curves
FOME provides for user-defined lookup tables and curves for use with Lua scripting. These tables and curves are set in the FOME configuration (via TunerStudio) and lookups are interpolated along their definition.
The tables and curves have user-defineable names up to sixteen characters long. Their names and definitions are configurable in the Advanced > Lua Calibrations menu in TunerStudio.
3D Tables
FOME provides four user-definable three-dimensional tables for use with Lua scripting. The first table affords the most precision, defined by single-precision floating-point values, while the remaining three tables are defined by 8-bit integers; all tables are eight by eight in dimension, defined by 16-bit integer coordinates.
TODO: insert TunerStudio Script Table dialog screenshots
Two functions are provided to interact with the user-defined tables:
2D Curves
FOME provides six user-definable two-dimensional curves for use with Lua scripting. The first two curves affords the most accuracy, defined by sixteen single-precision floating-point coordinates, while the remaining four curves are defined by eight single-precision floating-point coordinates.
TODO: insert TunerStudio Script Curve dialog screenshots
Two functions are provided to interact with the user-defined curves:
User-Defined Settings
FOME provides eight user-definable single-precision floating-point settings for use with Lua scripting.
Lua Interface Reference
Utilities
These functions are included in all builds of FOME unless otherwise noted.
mcu_standby()
mcu_standby
is only availble in FOME builds targetting STM32 F4 and STM32 F7 MCUs.
Causes the firmware to place the MCU into a low current consumption standby mode.
no parameters |
---|
print(message)
Print a line of text to the ECU's log.
parameter | type | description |
---|---|---|
message | string | The message to print. Pass a string (or number) and it will be printed to the log. |
setDebug(index, value)
Sets the debug channel of the specified index to the given value.
setDebug
only works when FOME's debug mode is set to Lua
.
parameter | type | description |
---|---|---|
index | integer | The index of the debug channel to set; 1 through 6. |
value | float | The value to set the specified debug channel to. |
setTickRate(frequency)
Set the frequency at which the firmware passes context to the Lua script. Primarily, this controls how often FOME calls
the script's onTick
function. Additionally, this affects how often other functions and callbacks of the script, like
onCanRx
, are invoked.
The default rate set at startup is 10 times per second (10 Hz).
parameter | type | description |
---|---|---|
frequency | float | The tick rate to set, in hertz. Values are clamped to be not less than 1 hertz and not more than 200 hertz. |
crc8_j1850(data, length)
TODO: computes the OBD-II (SAE J1850) CRC-8 cyclic redundancy check on up to eight bytes of data
parameter | type | description |
---|---|---|
data | integer table | |
length | integer |
interpolate(x1, y1, x2, y2, x)
Linearly interpolate a value x
along the line defined by two points (x1, y1)
and (x2, y2)
.
parameter | type | description |
---|---|---|
x1 | float | The x-axis value of the first point of the line. |
y1 | float | The y-axis value of the first point of the line. |
x2 | float | The x-axis value of the second point of the line. |
y2 | float | The y-axis value of the second point of the line. |
x | float | The x-axis value of the point to interpolate along the line defined by (x1, y1) and (x2, y2) . |
findTableIndex(name)
Determine the user-defined Lua script table index identified by its name.
parameter | type | description |
---|---|---|
name | string | The name of the user-defined table to determine the index of. |
table3d(index, x, y)
Lookup a linearly interpolated value from the specified user-defined Lua script table. Tables are identified by their 1-based index: 1, 2, 3, 4.
parameter | type | description |
---|---|---|
index | integer | The index of the user-defined table to lookup into; 1 through 4. |
x | float | The x-axis value to lookup in the specified table. |
y | float | The y-axis value to lookup in the specified table. |
findCurveIndex(name)
Determine the user-defined Lua script curve index identified by its name.
parameter | type | description |
---|---|---|
name | string | The name of the user-defined curve to determine the index of. |
curve(index, x)
Lookup a linearly interpolated value from the specified user-defined Lua script curve. Curves are identified by their 1-based index: 1, 2, 3, 4, 5, 6.
parameter | type | description |
---|---|---|
index | integer | The index of the user-defined curve to lookup into; 1 through 6. |
x | float | The x-axis value to lookup in the specified curve. |
findSetting(name, defaultValue)
Retrieve the value of the user-defined Lua setting identified by its name, or the supplied value if the setting does not exist.
This is most useful when the script developer and consumer are different people, and also when editing the Lua script in TunerStudio.
parameter | type | description |
---|---|---|
name | string | The name of the user-defined setting to retrieve the value of. |
defaultValue | float | The value to use if specified user-defined setting does not exist. |
Timer
Timer
is Lua type that keeps track of elapsed seconds. The timer does not initialize to a reset state; instead it
initializes to a "foreverish" value.
timer = Timer.new()
Timer.new()
no parameters |
---|
Timer.getElapsedSeconds()
Returns the number of seconds since the timer was last reset.
no parameters |
---|
Timer.reset()
Resets the timer to begin counting from zero.
no parameters |
---|
Pid
Pid
is a Lua type that implements a PID (proportional-integral-derivative) controller.
The implementation automatically tracks the time delta between Pid.get
invocations.
pid = Pid.new(1.5, 0.2, 0.1, -80, 80)
Pid.new(kp, ki, kd, min, max)
parameter | type | description |
---|---|---|
kp | float | , the proportional factor of the PID control. |
ki | float | , the integral factor of the PID control. |
kd | float | , the derivative factor of the PID control. |
min | float | The minimum output value of the PID control; output is limited above this value. |
max | float | The maximum output value of the PID control; output is limited below this value. |
Pid.get(target, input)
Retrieves the PID controller's output given the target setpoint and the output of the process or system the PID is controlling.
parameter | type | description |
---|---|---|
target | float | The target setpoint of the PID controller. |
input | float | The output of the process or system that is feedback to the PID controller. |
Pid.setOffset(offset)
Sets the amount to statically bias the PID controller output by.
parameter | type | description |
---|---|---|
offset | float | The amount to add to the computed PID controller output. |
Pid.reset()
Resets the PID controller.
no parameters |
---|
Input and Output
getAuxAnalog(index)
parameter | type | description |
---|---|---|
index | integer |
getAuxDigital(index)
parameter | type | description |
---|---|---|
index | integer |
getDigital(index)
parameter | type | description |
---|---|---|
index | integer |
readPin(name)
Returns the physical value of an MCU pin by its name.
parameter | type | description |
---|---|---|
name | string | The name of the MCU pin to return the value of; e.g. "PD15". |
startPwm(index, frequency, duty)
parameter | type | description |
---|---|---|
index | integer | The index of the PWM output to control; 0 through 7. |
frequency | float | The frequency to set the PWM output to. Values are clamped to be not less than 1 hertz and not more than 1000 hertz. |
duty | float | The duty cycle (on time) to set the PWM output to. Values are clamped to be not less than 0.0 and not more than 1.0. |
setPwmDuty(index, duty)
parameter | type | description |
---|---|---|
index | integer | The index of the PWM output to control; 0 through 7. |
duty | float | The duty cycle (on time) to set the PWM output to. Values are clamped to be not less than 0.0 and not more than 1.0. |
setPwmFreq(index, frequency)
parameter | type | description |
---|---|---|
index | integer | The index of the PWM output to control; 0 through 7. |
frequency | float | The frequency to set the PWM output to. Values are clamped to be not less than 1 hertz and not more than 1000 hertz. |
setLuaGauge(index, value)
Sets the given Lua gauge to the provided value. Currently two Lua guages are supported: indices 1 and 2.
This can also be accomplished by using the Lua Sensor
interface, but setLuaGauge
is more convenient to use.
parameter | type | description |
---|---|---|
index | integer | The index of the Lua gauge to set. |
value | number | The value to set the Lua gauge to. |
Sensors
hasSensor(index)
Checks whether a particular sensor is configured (whether it is currently valid or not).
parameter | type | description |
---|---|---|
index | integer | The index of the sensor to check; see sensor_type.h . |
getSensor(name)
Returns the value of a sensor by its name.
parameter | type | description |
---|---|---|
name | string | The name of the sensor to get the value of; see sensor_type.h . |
getSensorRaw(index)
Returns the raw value of a sensor by its name. For most sensors this means the analog voltage on the relevant input pin.
Returns 0 if the sensor doesn't support raw readings, isn't configured/valid, or has failed.
parameter | type | description |
---|---|---|
name | string | The name of the sensor to get the value of; see sensor_type.h . |
getSensorByIndex(index)
Returns the value of a sensor by its index.
parameter | type | description |
---|---|---|
index | integer | The index of the sensor to get the value of; see sensor_type.h . |
Sensor
Sensor
is a Lua type that allows to control the value of sensors. The type is implemented as a "stored-value" sensor,
that operates asynchronously and whose value is invalidated periodically upon a given timeout (initially: 100 milliseconds).
sensor = Sensor.new("OilPressure")
Sensor.new(name)
parameter | type | description |
---|---|---|
name | string | The name of the sensor to control; see sensor_type.h . |
Sensor.set(value)
Sets the controlled sensor's value as provided.
parameter | type | description |
---|---|---|
value | float | The value to set the controlled sensor to. |
Sensor.setRedundant(isRedundant)
Sets the redundancy-aspect of the controlled sensor.
parameter | type | description |
---|---|---|
isRedundant | boolean | Whether or not the controlled sensor is redundant. |
Sensor.setTimeout(timeoutMs)
Sets the timeout for the controlled sensor's stored-value.
parameter | type | description |
---|---|---|
timeoutMs | integer | How long the controlled sensors value is valid for, in milliseconds. |
Sensor.invalidate()
Invalidates the controlled sensor's stored-value.
no parameters |
---|
Firmware ... TODO
TODO
getOutput(name)
Returns the value of an "output" from FOME: allows to inspect "internal" firmware state.
TODO: reference list of valid outputs
parameter | type | description |
---|---|---|
name | string | The name of a FOME output/state to return the value of. |
setClutchUpState(isUp)
Use setClutchUpState
to tell FOME about CAN-based brake pedal.
parameter | type | description |
---|---|---|
isUp | boolean | Whether the clutch is up or not. |
setBrakePedalState(isUp)
Use setBrakePedalState
to tell FOME about CAN-based brake pedal.
parameter | type | description |
---|---|---|
isUp | boolean | Whether the brake pedal is up or not. |
setAcRequestState(isRequested)
Use setAcRequestState
to tell FOME about CAN-based A/C request.
parameter | type | description |
---|---|---|
isRequested | boolean | Whether the A/C is requested on or not. |
restartEtb()
TODO
no parameters |
---|
setEtbDisabled(isDisabled)
TODO
parameter | type | description |
---|---|---|
isDisabled | boolean | Whether the ETB is disabled or not. |
setIgnDisabled(isDisabled)
TODO: setIgnDisabled
function for all kinds of cranking safety systems
parameter | type | description |
---|---|---|
isDisabled | boolean | Whether the ignition is disabled or not. |
setAcDisabled(isDisabled)
TODO: Disable/suppress A/C functionality regardless of what and how enables it, an override kind of deal.
parameter | type | description |
---|---|---|
isDisabled | boolean | Whether the A/C is disabled or not. |
getTimeSinceAcToggleMs()
TODO
no parameters |
---|
getCalibration(name)
TODO: Gets current calibration value for specified scalar setting name
. For example getCalibration("cranking.rpm")
For complete list of possible calibration names (valid parameter values) and descriptions see value_lookup_generated.md
.
parameter | type | description |
---|---|---|
name | string | TODO |