Extended car channels: How To
If you have a car or are modding one that isn't supported by Telemetrick, here is how supporting it with your own Extended Channels in Motec.
Folder and files
You can either define extended channels in-app or in car itself.
in-app
First step is to create a new folder inside content/apps/lua/telemetrick/cars/ with exact same name as in content/cars.
For example: content/apps/lua/telemetrick/cars/tlmkformula2030
In this folder, create a new file: telemetrick_connection.lua
in car
If it's your own car, create a new lua file into content/cars/tlmkformula2030/extension/dataoverride/telemetrickconnection.lua.
When you will share this car, Telemetrick will automatically load Extended Channels from there.
telemetrick_connection.lua
Telemetrick app will look for this car definition file, and if it is there, it will require() it.
There is basically three things into this file:
- First part that defined required variables.
- extCar.loadExtChannels() that define Motec channels and their order.
- extCar.updateLogExt() which is called at each update() to get current values for each channel, depending on data rate.
We will see later that you can also define some custom Live Trace for these channels in same connection file.
lua script
Here is a basic example:
---@ext
if not string.startsWith(ac.getCarID(0), "tlmk_formula_2030") then
return
end
-- is v1.70+ function there:
local _Tlmk
if getTmlkLogger then
_Tlmk = getTmlkLogger()
else
_Tlmk = app
end
car = {index = 0}
ecuConnectStuct = {
ac.StructItem.key(ac.getCarID(car.index) .. "_ecu_" .. car.index),
differentialEntry = ac.StructItem.float(),
differentialMid = ac.StructItem.float(),
differentialExitHispd = ac.StructItem.float(),
liveBrakeBias = ac.StructItem.float(),
throttleRaw = ac.StructItem.float(),
}
ECU = ac.connect(ecuConnectStuct, true, ac.SharedNamespace.CarScript)
You check if current car is the right one (which always should anyway), and call same ac.connect() as car script. Here, script has ECU var table.
loadExtChannels()
Here you will have to define Motec channels, and their orders.
---Called by Core App at init to declare extended channels params and order.
---If no `freq` param in channel, will be 10Hz.
---`freq` either 1 10 20 "user".
---`ordered_keys` in ascending `freq`
---@param track string @Optional app.trackLayout
---@return T extChannels and T ordered_keys
extCar.loadExtChannels = function()
extChannels = {
-- 1Hz
puTemperature = {
freq = 1,
datatype = 7,
datasize = 4,
mult = 1,
name = "PU Temperature",
shortname = "puTemperature",
units = "deg",
},
-- 10Hz
differentialEntry = {
add = 1,
name = "Diff Entry",
shortname = "differentialEntry"
},
differentialMid = {
add = 1,
name = "Diff Mid",
shortname = "differentialMid"
},
differentialExitHispd = {
add = 1,
name = "Diff Exit",
shortname = "differentialExitHispd"
},
-- 20Hz
liveBrakeBias = {
freq = 20,
datatype = 7,
datasize = 4,
mult = 100,
name = "Live Brake Bias",
shortname = "liveBrakeBias",
units = "%",
}
-- user max data rate
throttleRaw = {
freq = "user",
datatype = 7,
datasize = 4,
mult = 100,
name = "Throttle Raw",
shortname = "throttleRaw",
units = "%",
},
}
ordered_keys = {
"puTemperature",
"differentialEntry",
"differentialMid",
"differentialExitHispd",
"liveBrakeBias",
"throttleRaw"
}
return extChannels, ordered_keys
end
Channel definition
- default (int):
mychannel = {
name = "My Channel",
shortname = "mychannel"
}
- small float:
mychannel = {
datatype = 3,
datasize = 2,
name = "My Channel",
shortname = "mychannel"
}
- long float (small values with lot of decimals):
mychannel = {
datatype: 7,
datasize: 4,
name = "My Channel",
shortname = "mychannel"
}
- unit:
You can add a channel unit like %, m, mm, m/s, G, deg/s, rad/s, deg, rpm, kJ, etc. If unitless just remove this param.
- conversion:
mychannel = {
mult = 100, -- Will multiply reported value by 100
add = 1, -- Will add 1 to reported value
subFrom = 100 -- Will substract value from 100
}
updateLogExt()
This function will add your values, in defined order in loadExtChannels.
---Called by Core App to update current values with extended channels values for a given data rate.
---Values in same order as declared in ordered_keys
---Called without rate in pre v1.67 app and for UI live update.
---@param lineTable T, current car values
---@param rate int, data rate
---@return T lineTable
extCar.updateLogExt = function(lineTable, rate)
if rate == 1 or not rate then lineTable[#lineTable + 1] = ECU.puTemperature end
if rate == 10 or not rate then
table.insert(lineTable, ECU.differentialEntry)
table.insert(lineTable, ECU.differentialMid)
table.insert(lineTable, ECU.differentialExitHispd)
end
if rate == 20 or not rate then
lineTable[#lineTable + 1] = ECU.brakeBiasLive
end
if rate == _Tlmk.currentDataRate or not rate then
lineTable[#lineTable + 1] = ECU.throttleRaw
end
return lineTable
end
For performance consideration, this function being called at each script update(), you should not do any conversion here, apart boolean:
table.insert(lineTable, connections.ECU.isEngineRunning and 1 or 0)
So:
- Telemetrick app load and search for connection file.
- If connection file exist, it
require()it once. - At app init(), Telemetrick call
extCar.loadExtChannels()once. - At each script update(), Telemetrick call
extCar.updateLogExt(), which much return data in same order as defined in returnedordered_keys.
In game, you can check current values in app channels tab when in pit. If you see them, and updating, all should be right in Motec file!
Live Trace
You can also define some custom Live Trace for these channels in same connection file.
--Add some Livre Traces:
local STRformat = string.format
local appTrace = getTmlkAppTrace()
table.insert(appTrace.newTlist, 'MGUKpower')
appTrace.tracesRef['brakeBiasLive'] = {
type = 'brakeBiasLive',
name = 'Live BB',
show = true,
color = rgbm(1, 0.8, 0, 1),
width = 1.35,
min = 30,
max = 70,
help = "Tlmk F. Live BB",
update = function(thisTrace)
local range = thisTrace.max - thisTrace.min
local v = ECU.brakeBiasLive
thisTrace.data[#thisTrace.data+1] = ((v + range/2) / range) * 100
return STRformat("%02.1f%%", v)
end,
}