-- CVT Transmission Type-A v0.8 by Vegetable Studio -- Please visit "https://www.patreon.com/vegetable_studio" for instructions -- Essentials local raw = ac.accessCarPhysics() local car = ac.getCar(0) local engine = ac.INIConfig.carData(0, 'engine.ini') local drivetrain = ac.INIConfig.carData(0, 'drivetrain.ini') local tyre = ac.INIConfig.carData(0, 'tyre.ini') local gearCount = car.gearCount local limiter = car.rpmLimiter local torque = ac.DataLUT11.load(engine:get('HEADER', 'POWER_CURVE', 'power.lut')) local idleRpm = engine:get('ENGINE_DATA', 'MINIMUM', 800) local clutchMaxTorque = drivetrain:get('CLUTCH', 'MAX_TORQUE', 600) local gearsFinalRatio = drivetrain:get('GEARS', 'FINAL', 4.4) local circumference = tyre:get('REAR', 'RADIUS', 0.32) * 2 * math.pi local rpmToKmh = circumference / 1000 * 60 local gearRatios = {} for i = 1, gearCount do gearRatios[i] = drivetrain:get('GEARS', 'GEAR_' .. tostring(i), 0) end local gear, speed, rpmEngine, throttle = 1, 0, 0, 0 -- Values for torque converter simulation local stallRpm = 2000 * math.round(idleRpm / 1000) local stallTorque = torque:get(stallRpm) local stallPower = stallRpm * stallTorque / 5250 local kFactor = math.round(stallRpm / math.sqrt(stallTorque), -1) local lockUpMap = ac.DataLUT11.parse('(|' .. tostring(stallRpm * 1 / gearRatios[1] / gearsFinalRatio * rpmToKmh) .. '=0|'.. tostring(stallRpm * 1.25 / gearRatios[1] / gearsFinalRatio * rpmToKmh) ..'=1|)') local speedLag = 0 local rpmWheel, rpmDiff = 0, 0 local tcPressure = 0 local tcLoad = 0 local torqueMult = 1 local torqueEngine = 0 local targetFinal = gearsFinalRatio local torqueConverter, lockUp = 0, 0 -- Values for gear ratio target calculation local maxPower, maxPowerRpm = 0, 0 for i = math.ceil(idleRpm / 100) * 100, math.floor(limiter / 100) * 100, 100 do if torque:get(i) * i > maxPower then maxPower = torque:get(i) * i maxPowerRpm = i end end local rpmMap = ac.DataLUT11.parse('(|0=' .. tostring(math.ceil(idleRpm / 500) * 500) .. '|0.9=' .. tostring(math.min(maxPowerRpm, limiter * 0.94)) .. '|)') local targetRpm, targetRatio = 0, 0 function script.update(dt) -- Disable H-shifter to stop overriding engaged gear if raw.isShifterSupported == true then raw.isShifterSupported = false end -- -- Update final ratio & top speeds when setup is changed, Not working at the moment -- if math.abs(raw.gearsFinalRatio - targetFinal) > 0.1 then -- gearsFinalRatio = raw.gearsFinalRatio -- for i = 1, gearCount do -- topSpeeds[i] = limiter * 0.99 / gearRatios[i] / gearsFinalRatio * rpmToKmh -- end -- end -- Essentials gear = math.max(1, car.gear) speed = math.round(car.poweredWheelsSpeed, 2) rpmEngine = math.max(raw.rpm, 1) throttle = raw.gas torqueEngine = math.max(car.drivetrainTorque, 0) -- Torque converter simulation speedLag = math.applyLag(speedLag, speed, 0.95, dt) rpmWheel = math.max(speed / rpmToKmh * gearsFinalRatio * gearRatios[gear], 1) rpmDiff = math.max(rpmEngine - rpmWheel, 0) tcPressure = math.pow(rpmDiff / kFactor, 2) tcLoad = math.min(car.drivetrainPower / stallPower, 1) torqueMult = 1 + (rpmDiff / stallRpm) * (1 - math.min(rpmWheel / stallRpm, 1)) targetFinal = gearsFinalRatio * torqueMult torqueConverter = math.clamp((tcPressure / clutchMaxTorque * (1 - tcLoad) + math.sqrt(torqueEngine / clutchMaxTorque) * tcLoad), 0, 1) -- Clutch lock-up feature lockUp = lockUpMap:get(speedLag) -- Calculates gear ratio target targetRpm = math.applyLag(targetRpm, rpmMap:get(throttle), 0.98, dt) if car.gear > 0 then targetRatio = math.clampN(targetRpm / (speed / rpmToKmh * gearsFinalRatio), gearRatios[gearCount], gearRatios[1]) targetFinal = targetFinal / gearRatios[gear] * targetRatio end -- Actual physics override ac.setGearsFinalRatio(targetFinal) raw.clutch = torqueConverter + (1 - torqueConverter) * lockUp --Debug ac.debug("Shift Mode", 'D') -- ac.debug("Original Final Ratio", gearsFinalRatio) -- ac.debug("Target RPM", targetRpm) -- ac.debug("Target Ratio", targetRatio) -- ac.debug("Current Final Ratio", raw.gearsFinalRatio) -- ac.debug("K Factor", kFactor) -- ac.debug("Stator Pressure", math.round(tcPressure) .. ' Nm') -- ac.debug("Torque Multiplication", math.round(torqueMult, 2)) -- ac.debug("Clutch Lock-Up", math.round(lockUp * 100) .. '%') -- ac.debug("Torque Converter", math.round(torqueConverter, 2)) -- ac.debug("Slippage", math.round(((rpmEngine / rpmWheel) - 1) * 100) .. '%') -- ac.debug("Torque Output", math.round(torqueEngine * torqueMult) .. ' Nm') end