VE Lua Documentation

Press F to search!

onFFBConfigChanged

Definition


-- @/lua/vehicle/hydros.lua:608

local function onFFBConfigChanged(newFFBConfig)
  turnOffFFBInterfaces()

  if not virtualWheelEnabled then
    FFBID = -1
  end
  if #FFBHydros ~= 0 and newFFBConfig and newFFBConfig.steering then
    y1 = 0

    FFBHydrosExist = true
    FFBsmooth:set(0)
    curForceLimitSmoother:set(0)
    log("D", "hydros.init", "Response to FFB config request: "..dumps(newFFBConfig))

    local ffbConfig = newFFBConfig.steering
    local ffbConfig_accelerate = newFFBConfig.accelerate
    local ffbConfig_brake = newFFBConfig.brake

    FFBID = ffbConfig.FFBID or -1
    FFBID_accelerate = ffbConfig_accelerate and ffbConfig_accelerate.FFBID or -1
    FFBID_brake = ffbConfig_brake and ffbConfig_brake.FFBID or -1

    if FFBID >= 0 then
      M.wheelFFBForceLimit = FFmax
      local ffbParams = ffbConfig.ffbParams
      if ffbParams then
        local frequency = 0
        if ffbParams.forceCoef ~= nil then M.wheelFFBForceCoef = ffbParams.forceCoef end
        if ffbParams.isVibrationEnabled ~= nil then M.enableVibration = ffbParams.isVibrationEnabled end
        if ffbParams.enableThrottleForceFeedback ~= nil then M.enableThrottleForceFeedback = ffbParams.enableThrottleForceFeedback end
        if ffbParams.enableBrakeForceFeedback ~= nil then M.enableBrakeForceFeedback = ffbParams.enableBrakeForceFeedback end
        if ffbParams.torqueDesired and ffbParams.torqueCurrent then M.wheelFFBForceLimit = FFmax * clamp(ffbParams.torqueDesired / ffbParams.torqueCurrent, 0.1, 1) end
        M.torqueCurrent = ffbParams.torqueCurrent or 100
        if ffbParams.softlockForce~= nil then softlockForceCoef = clamp(ffbParams.softlockForce, 0, 1) end
        if type(input.lowspeedCoefFFB) == "boolean" then
          log("I", "", string.format("This vehicle's steering hydro has specified a custom lowspeedCoefFFB setting. Overriding the binding setting lowspeedCoef=%s with the hydro setting lowspeedCoef=%s", dumps(ffbParams.lowspeedCoef), dumps(input.lowspeedCoefFFB)))
          ffbParams.lowspeedCoef = input.lowspeedCoefFFB
        end
        if ffbParams.lowspeedCoef then M.wheelFFBForceCoefLowSpeed = ffbParams.forceCoef / 10 end
        if ffbParams.smoothing ~= nil then wheelFFBSmoothing = ffbParams.smoothing * 0.7 end
        if ffbParams.gforceCoef ~= nil then M.GforceCoef = ffbParams.gforceCoef  end
        if ffbParams.frequency ~= nil then frequency = tonumber(ffbParams.frequency) or 0 end
        responseCorrected = ffbParams.responseCorrected == true
        if ffbParams.responseCurve ~= nil then responseCurve = ffbParams.responseCurve end
        if responseCorrected then
          responseCurve = processResponseCurve(responseCurve)
        end

        if M.enableVibration then
          FFBHydrosExist = false
        end

        wheelFFBSmoothing2automatic = ffbParams.smoothing2automatic ~= false
        -- IMPORTANT: these equations exist in 3 places in hydros.lua, 2 places in options.js, and 1 place in bindings.lua
        if wheelFFBSmoothing2automatic then
          wheelFFBSmoothing2 = max(5000, (500 - wheelFFBSmoothing)*100+5000)
        else
          wheelFFBSmoothing2 = ffbParams.smoothing2 * 109 + 500
        end

        local automaticRate = frequency == 0
        if not ffbConfig.ffbSendms then
          BNG_LOG_ERR("Automatic measurement of FFB send ms unavailable, using 60Hz as failsafe")
          ffbConfig.ffbSendms = 1000/60
        end
        -- use heuristics to detect a safe update rate for FFB, based on ffbSendms. an excessive rate can overload the drivers and cause strange side effects
        local detectedFrequency = 1000/ffbConfig.ffbSendms
        local clampedFrequency = clamp(detectedFrequency, 30, 2000)
        local safeFrequency = clamp(math.floor(clampedFrequency * 0.5), 30, 400) -- leave time for actual physics computation too
        local finalFrequency = safeFrequency
        if not automaticRate then
          finalFrequency = clamp(frequency, 30, 2000)
          if finalFrequency > safeFrequency then
            log("W", "", "User has chosen an excessive force feedback update rate of "..frequency.." Hz. To avoid severe framerate loss and broken force feedback, the estimated safe rate of "..safeFrequency.." Hz will be used instead")
            finalFrequency = min(safeFrequency, finalFrequency)
          end
        end
        FFBperiod = M.enableFFBflood and 0 or (1 / math.floor(finalFrequency + 0.5)) -- allow unlimited update in case flood debugging
        log("D", "hydros.init", string.format("FFB update rate heuristics: potentially supported freq: %5.1f, clamped freq: %5.1f, safe freq: %5.1f", detectedFrequency, clampedFrequency, safeFrequency))
        log("D", "hydros.init", string.format("FFB settings: requested freq: %5.3f, rate selection mode: %s, final used frequency: %5.3f", frequency, automaticRate and "auto" or "manual",  finalFrequency))
        log("D", "hydros.init", string.format("FFB summary: vehicle: %s (id %s), type: '%s', strength: %5.3f, smoothing: %5.3f", dumps(v.data.vehicleDirectory), dumps(obj:getId()), "steering", M.wheelFFBForceCoef, wheelFFBSmoothing))
        turnOffFFBInterfaces()
        nextDriverUpdate = clockhp() + FFBperiod
      else
        FFBID = -1
        log("E", "hydros.init", "Couldn't find ffbParams in ffbconfig: ffbParams: "..dumps(ffbParams).."\nffbConfig.ffbParams: "..dumps(ffbConfig.ffbParams))
      end
    end
  end
end

Callers

@/lua/ge/extensions/core/input/bindings.lua
  for _,veh in ipairs(getAllVehicles()) do
    veh:queueLuaCommand("hydros.onFFBConfigChanged("..serialize(getFFBConfig(veh))..")")
  end