ardupilot/libraries/AP_Scripting/drivers/EFI_DLA.lua

189 lines
4.9 KiB
Lua

--[[
DLA serial EFI protocol
Note that this protocol is gap framed, no CRC
https://www.austars-model.com/dla-232cc-uavuas-engine-optional-one-key-startauto-startergenerator_g17937.html
--]]
local PARAM_TABLE_KEY = 41
local PARAM_TABLE_PREFIX = "EFI_DLA_"
local MAV_SEVERITY = {EMERGENCY=0, ALERT=1, CRITICAL=2, ERROR=3, WARNING=4, NOTICE=5, INFO=6, DEBUG=7}
-- bind a parameter to a variable given
local function bind_param(name)
local p = Parameter()
assert(p:init(name), string.format('could not find %s parameter', name))
return p
end
-- add a parameter and bind it to a variable
local function bind_add_param(name, idx, default_value)
assert(param:add_param(PARAM_TABLE_KEY, idx, name, default_value), string.format('could not add param %s', name))
return bind_param(PARAM_TABLE_PREFIX .. name)
end
-- setup script specific parameters
assert(param:add_table(PARAM_TABLE_KEY, PARAM_TABLE_PREFIX, 8), 'could not add param table')
--[[
// @Param: EFI_DLA_ENABLE
// @DisplayName: EFI DLA enable
// @Description: Enable EFI DLA driver
// @Values: 0:Disabled,1:Enabled
// @User: Standard
--]]
EFI_DLA_ENABLE = bind_add_param("ENABLE", 1, 0)
--[[
// @Param: EFI_DLA_LPS
// @DisplayName: EFI DLA fuel scale
// @Description: EFI DLA litres of fuel per second of injection time
// @Range: 0.00001 1
// @Units: litres
// @User: Standard
--]]
EFI_DLA_LPS = bind_add_param("LPS", 2, 0.001)
if EFI_DLA_ENABLE:get() ~= 1 then
return
end
local uart = serial:find_serial(0) -- first scripting serial
if not uart then
gcs:send_text(MAV_SEVERITY.ERROR, "EFI_DLA: unable to find scripting serial")
return
end
uart:begin(115200)
local efi_backend = efi:get_backend(0)
if not efi_backend then
gcs:send_text(MAV_SEVERITY.ERROR, "EFI_DLA: unable to find EFI backend")
return
end
--[[
discard n bytes
--]]
local function discard_bytes(n)
for _ = 1, n do
uart:read()
end
end
local function read_bytes(n)
local ret = ""
for _ = 1, n do
ret = ret .. string.char(uart:read())
end
return ret
end
local state = {}
state.last_read_us = uint32_t(0)
state.total_fuel_cm3 = 0.0
--[[
check for input and parse data
--]]
local function check_input()
local n_bytes = uart:available():toint()
--gcs:send_text(MAV_SEVERITY.INFO, string.format("n_bytes=%u %.2f", n_bytes, millis():tofloat()*0.001))
if n_bytes < 82 then
return
end
if n_bytes > 82 then
discard_bytes(n_bytes)
return
end
state.seconds, state.pw1, state.pw2 = string.unpack("<HHH", read_bytes(6))
state.rpm, state.adv_deg, state.squirt = string.unpack("<HhB", read_bytes(5))
state.engine, state.afrtgt1, state.afrtgt2 = string.unpack("<BBB", read_bytes(3))
state.wbo2_en1, state.wbo2_en2, state.baro = string.unpack("<BBh", read_bytes(4))
state.map, state.mat, state.clt = string.unpack("<hhh", read_bytes(6))
state.tps, state.batt = string.unpack("<hh", read_bytes(4))
state.last_read_us = micros()
-- discard the rest
discard_bytes(uart:available():toint())
end
--[[
request more data
--]]
local function request_data()
--uart:write(string.byte("a"))
uart:write(0x61)
end
local function farenheight_to_C(v)
return (v + 459.67) * 0.55556
end
--[[
update EFI state
--]]
local function update_EFI()
if state.last_read_us == uint32_t(0) then
return
end
local cylinder_state = Cylinder_Status()
local efi_state = EFI_State()
-- 4.3.x incorrectly uses C instead of kelvin
-- local C_TO_KELVIN = 273.2
cylinder_state:cylinder_head_temperature(farenheight_to_C(state.clt*0.1))
cylinder_state:exhaust_gas_temperature(farenheight_to_C(state.mat*0.1))
cylinder_state:ignition_timing_deg(state.adv_deg*0.1)
local inj_time_ms = (state.pw1+state.pw2)*0.001
cylinder_state:injection_time_ms(inj_time_ms)
efi_state:engine_speed_rpm(state.rpm)
efi_state:atmospheric_pressure_kpa(state.baro*0.1)
efi_state:intake_manifold_pressure_kpa(state.map*0.1)
efi_state:intake_manifold_temperature(farenheight_to_C(state.mat*0.1))
efi_state:throttle_position_percent(math.floor(state.tps*0.1))
efi_state:ignition_voltage(state.batt*0.1)
local now_us = micros()
local dt = (now_us - state.last_read_us):tofloat()*1.0e-6
state.last_read_us = now_us
local revs = state.rpm * 60.0 * dt
local inj_time = revs * inj_time_ms * 0.001
local fuel_used_cm3 = EFI_DLA_LPS:get() * 0.001 * inj_time
state.total_fuel_cm3 = state.total_fuel_cm3 + fuel_used_cm3
efi_state:fuel_consumption_rate_cm3pm((fuel_used_cm3 / dt) * 60.0)
efi_state:estimated_consumed_fuel_volume_cm3(state.total_fuel_cm3)
efi_state:cylinder_status(cylinder_state)
efi_state:last_updated_ms(millis())
-- Set the EFI_State into the EFI scripting driver
efi_backend:handle_scripting(efi_state)
end
--[[
main update function
--]]
local function update()
check_input()
update_EFI()
request_data()
return update, 100
end
gcs:send_text(MAV_SEVERITY.INFO, "EFI_DLA: loaded")
return update()