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:

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

mychannel = {
	name = "My Channel",
	shortname = "mychannel"
}
mychannel = {
	datatype = 3,
	datasize = 2,
	name = "My Channel",
	shortname = "mychannel"
}
mychannel = {
	datatype: 7,
	datasize: 4,
	name = "My Channel",
	shortname = "mychannel"
}

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.

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:

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,
}