types
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
--@include ./powertrain_component.txt
|
||||
--@include /koptilnya/libs/constants.txt
|
||||
|
||||
---@type PowertrainComponent
|
||||
local PowertrainComponent = require('./powertrain_component.txt')
|
||||
|
||||
require('/koptilnya/libs/constants.txt')
|
||||
@@ -88,4 +89,7 @@ function Clutch:forwardStep(torque, inertia)
|
||||
return math.clamp(returnTorque, -self.slipTorque, self.slipTorque)
|
||||
end
|
||||
|
||||
---@type fun(vehicle: KPTLVehicle, name?: string, config?: ClutchConfig): Clutch
|
||||
Clutch.new = Clutch.new
|
||||
|
||||
return Clutch
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
--@include /koptilnya/libs/constants.txt
|
||||
--@include ./powertrain_component.txt
|
||||
|
||||
---@type PowertrainComponent
|
||||
local PowertrainComponent = require('./powertrain_component.txt')
|
||||
|
||||
require('/koptilnya/libs/constants.txt')
|
||||
@@ -47,8 +48,7 @@ function Differential:initialize(vehicle, name, config)
|
||||
|
||||
self.wireOutputs = {
|
||||
[string.format('%s_Torque', self.name)] = 'number',
|
||||
[string.format('%s_W', self.name)] = 'number',
|
||||
[string.format('%s_MzDiff', self.name)] = 'number',
|
||||
[string.format('%s_RPMDiff', self.name)] = 'number',
|
||||
}
|
||||
|
||||
self.finalDrive = config.FinalDrive or 4
|
||||
@@ -66,6 +66,7 @@ function Differential:initialize(vehicle, name, config)
|
||||
self.steerAngle = 0
|
||||
|
||||
self.mzDiff = 0
|
||||
self.rpmDiff = 0
|
||||
end
|
||||
|
||||
---@param component PowertrainComponent
|
||||
@@ -90,8 +91,7 @@ function Differential:updateWireOutputs()
|
||||
PowertrainComponent.updateWireOutputs(self)
|
||||
|
||||
wire.ports[string.format('%s_Torque', self.name)] = self.torque
|
||||
wire.ports[string.format('%s_W', self.name)] = self.angularVelocity
|
||||
wire.ports[string.format('%s_MzDiff', self.name)] = self.mzDiff
|
||||
wire.ports[string.format('%s_RPMDiff', self.name)] = self.rpmDiff
|
||||
|
||||
if self.outputA ~= nil then
|
||||
self.outputA:updateWireOutputs()
|
||||
@@ -157,49 +157,60 @@ function Differential:forwardStep(torque, inertia)
|
||||
tqA = self.outputA:forwardStep(tqA, inertia * 0.5 * math.pow(self.finalDrive, 2) + aI)
|
||||
tqB = self.outputB:forwardStep(tqB, inertia * 0.5 * math.pow(self.finalDrive, 2) + bI)
|
||||
|
||||
if self.CONFIG.Type == DIFFERENTIAL_TYPES.Locking then
|
||||
local avg = (self.outputA.angularVelocity + self.outputB.angularVelocity) / 2
|
||||
|
||||
self.outputA:queryAngularVelocity(avg)
|
||||
self.outputB:queryAngularVelocity(avg)
|
||||
end
|
||||
|
||||
self.rpmDiff = self.outputA:getRPM() - self.outputB:getRPM()
|
||||
|
||||
-- // REFACTOR
|
||||
if self.steerLock ~= 0 then
|
||||
local outputA = self.outputA --[[@as Wheel]]
|
||||
local outputB = self.outputB --[[@as Wheel]]
|
||||
if self.outputA.customWheel ~= nil and self.outputB.customWheel ~= nil then
|
||||
if self.steerLock ~= 0 then
|
||||
local outputA = self.outputA --[[@as Wheel]]
|
||||
local outputB = self.outputB --[[@as Wheel]]
|
||||
|
||||
local steerInertia = (aI + bI) / 2
|
||||
local driverInput = 15
|
||||
local steerInertia = (aI + bI)
|
||||
local driverInput = 3
|
||||
|
||||
local localVelocityLength = chip():getVelocity():getLength()
|
||||
local MPH = localVelocityLength * (15 / 352)
|
||||
local KPH = MPH * 1.609
|
||||
local localVelocityLength = chip():getVelocity():getLength()
|
||||
local MPH = localVelocityLength * (15 / 352)
|
||||
local KPH = MPH * 1.609
|
||||
|
||||
local assist = math.clamp(10.0 / math.sqrt(KPH / 3), 2.0, 10.0)
|
||||
local assist = math.clamp(10.0 / math.sqrt(KPH / 3), 2.0, 10.0) / 2
|
||||
|
||||
local inputForce = driverInput * assist
|
||||
local inputForce = driverInput * assist
|
||||
|
||||
local inputTorque = self.vehicle.steer * inputForce
|
||||
local inputTorque = self.vehicle.steer * inputForce
|
||||
|
||||
local mzDiff = outputA.customWheel.mz - outputB.customWheel.mz
|
||||
local mzDiff = (outputB.customWheel.mz - outputA.customWheel.mz) * TICK_INTERVAL / 2
|
||||
|
||||
self.mzDiff = mzDiff
|
||||
self.mzDiff = math.lerp(0.1, self.mzDiff, mzDiff)
|
||||
|
||||
local steerTorque = mzDiff * -1 + inputTorque
|
||||
local steerTorque = self.mzDiff * 1 + inputTorque
|
||||
|
||||
local steerAngularAccel = steerTorque / steerInertia
|
||||
local steerAngularAccel = steerTorque / steerInertia
|
||||
|
||||
self.steerAngle = math.clamp(self.steerAngle + steerAngularAccel * TICK_INTERVAL, -self.steerLock, self.steerLock)
|
||||
self.steerAngle = math.clamp(self.steerAngle + math.deg(steerAngularAccel) * TICK_INTERVAL, -self.steerLock, self.steerLock)
|
||||
|
||||
local wheelbase = 2.05
|
||||
local trackWidth = 1.124
|
||||
local radius = wheelbase / math.tan(math.rad(self.steerAngle))
|
||||
local wheelbase = 2.05
|
||||
local trackWidth = 1.124
|
||||
local radius = wheelbase / math.tan(math.rad(self.steerAngle))
|
||||
|
||||
local innerAngle = math.deg(math.atan(wheelbase / (radius - (trackWidth / 2))))
|
||||
local outerAngle = math.deg(math.atan(wheelbase / (radius + (trackWidth / 2))))
|
||||
local innerAngle = math.deg(math.atan(wheelbase / (radius - (trackWidth / 2))))
|
||||
local outerAngle = math.deg(math.atan(wheelbase / (radius + (trackWidth / 2))))
|
||||
|
||||
outputA.customWheel.steerAngle = outerAngle + self.toeAngle * outputA.customWheel.direction
|
||||
outputB.customWheel.steerAngle = innerAngle + self.toeAngle * outputB.customWheel.direction
|
||||
else
|
||||
local outputA = self.outputA --[[@as Wheel]]
|
||||
local outputB = self.outputB --[[@as Wheel]]
|
||||
outputA.customWheel.steerAngle = outerAngle + self.toeAngle * outputA.customWheel.direction
|
||||
outputB.customWheel.steerAngle = innerAngle + self.toeAngle * outputB.customWheel.direction
|
||||
else
|
||||
local outputA = self.outputA --[[@as Wheel]]
|
||||
local outputB = self.outputB --[[@as Wheel]]
|
||||
|
||||
outputA.customWheel.steerAngle = self.toeAngle * outputA.customWheel.direction
|
||||
outputB.customWheel.steerAngle = self.toeAngle * outputB.customWheel.direction
|
||||
outputA.customWheel.steerAngle = self.toeAngle * outputA.customWheel.direction
|
||||
outputB.customWheel.steerAngle = self.toeAngle * outputB.customWheel.direction
|
||||
end
|
||||
end
|
||||
|
||||
return tqA + tqB
|
||||
@@ -212,21 +223,63 @@ end
|
||||
|
||||
---@return number, number
|
||||
local function _lockingDiffTorqueSplit(tq, aW, bW, aI, bI, biasAB, preload, stiffness, powerRamp, coastRamp, slipTorque)
|
||||
aTq = tq * 0.5
|
||||
bTq = tq * 0.5
|
||||
return tq * 0.5, tq * 0.5
|
||||
-- -- Разность скоростей между выходами
|
||||
-- local deltaW = aW - bW
|
||||
|
||||
local syncTorque = (aW - bW) * stiffness * (aI + bI) * 0.5 / TICK_INTERVAL
|
||||
-- -- Расчет "проскальзывающего" момента между сторонами
|
||||
-- local slip = math.abs(deltaW)
|
||||
|
||||
aTq = aTq - syncTorque
|
||||
bTq = bTq + syncTorque
|
||||
-- -- Применяем преднагрузку и жесткость, чтобы определить базовый момент блокировки
|
||||
-- local lockingTorque = preload + stiffness * deltaW
|
||||
|
||||
-- -- Определение направления нагрузки: ускорение или торможение
|
||||
-- local ramp = tq >= 0 and powerRamp or coastRamp
|
||||
|
||||
-- -- Применяем ramp к разности скоростей, усиливая/ослабляя блокировку
|
||||
-- local rampTorque = slip * ramp
|
||||
|
||||
-- -- Итоговый момент передачи между сторонами
|
||||
-- local transferTorque = lockingTorque + rampTorque
|
||||
|
||||
-- -- Ограничиваем передачу момента порогом проскальзывания
|
||||
-- if transferTorque > slipTorque then
|
||||
-- transferTorque = slipTorque
|
||||
-- end
|
||||
|
||||
-- -- Учитываем биас (смещение баланса)
|
||||
-- local maxBias = biasAB
|
||||
-- local biasLimit = tq * (maxBias - 1) / (maxBias + 1)
|
||||
|
||||
-- -- Финальный момент, передаваемый между сторонами, с учетом направления
|
||||
-- local direction = deltaW > 0 and -1 or 1
|
||||
-- local finalTorque = direction * transferTorque
|
||||
|
||||
-- -- Применяем финальный момент к каждой стороне, ограничивая его bias'ом
|
||||
-- local aTorque = tq * 0.5 + math.min(finalTorque, biasLimit)
|
||||
-- local bTorque = tq * 0.5 - math.min(finalTorque, biasLimit)
|
||||
|
||||
-- -- Возвращаем обновленные значения угловых скоростей
|
||||
-- return aTorque, bTorque
|
||||
|
||||
-- local aTq = tq * 0.5
|
||||
-- local bTq = tq * 0.5
|
||||
|
||||
-- local syncTorque = (aW - bW) * 1e6 * (aI + bI) / TICK_INTERVAL
|
||||
|
||||
-- aTq = aTq - syncTorque
|
||||
-- bTq = bTq + syncTorque
|
||||
|
||||
-- -- print(aTq, bTq)
|
||||
|
||||
-- return aTq, bTq
|
||||
|
||||
return aTq, bTq
|
||||
-- local sumI = aI + bI
|
||||
-- local w = aI / sumI * aW + bI / sumI * bW
|
||||
-- local aTqCorr = (w - aW) * aI -- / dt
|
||||
-- local aTqCorr = (w - aW) * aI / TICK_INTERVAL
|
||||
-- aTqCorr = aTqCorr * stiffness
|
||||
|
||||
-- local bTqCorr = (w - bW) * bI -- / dt
|
||||
-- local bTqCorr = (w - bW) * bI / TICK_INTERVAL
|
||||
-- bTqCorr = bTqCorr * stiffness
|
||||
|
||||
-- local biasA = math.clamp(0.5 + (bW - aW) * 0.1 * stiffness, 0, 1)
|
||||
@@ -293,4 +346,7 @@ end
|
||||
|
||||
Differential.TYPES = DIFFERENTIAL_TYPES
|
||||
|
||||
---@type fun(vehicle: KPTLVehicle, name?: string, config?: DifferentialConfig): Differential
|
||||
Differential.new = Differential.new
|
||||
|
||||
return Differential
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
--@include ./powertrain_component.txt
|
||||
--@include /koptilnya/libs/constants.txt
|
||||
|
||||
---@type PowertrainComponent
|
||||
local PowertrainComponent = require('./powertrain_component.txt')
|
||||
|
||||
require('/koptilnya/libs/constants.txt')
|
||||
@@ -65,10 +66,10 @@ function Engine:initialize(vehicle, name, config)
|
||||
self.returnedTorque = 0
|
||||
|
||||
if CLIENT then
|
||||
-- --@include /koptilnya/engine_sound_2.txt
|
||||
-- local Sound = require('/koptilnya/engine_sound_2.txt')
|
||||
--@include /koptilnya/engine_sound_2.txt
|
||||
local Sound = require('/koptilnya/engine_sound_2.txt')
|
||||
|
||||
-- Sound(self.maxRPM, chip())
|
||||
Sound(self.maxRPM, chip())
|
||||
end
|
||||
end
|
||||
|
||||
@@ -152,16 +153,19 @@ function Engine:forwardStep(torque, inertia)
|
||||
self.angularVelocity = self.angularVelocity + finalTorque / inertiaSum * TICK_INTERVAL
|
||||
self.angularVelocity = math.max(self.angularVelocity, 0)
|
||||
|
||||
-- net.start('ENGINE_RPM')
|
||||
-- net.writeFloat(self:getRPM() / self.maxRPM)
|
||||
-- net.send(self.vehicle.playersConnectedToHUD, true)
|
||||
net.start('ENGINE_RPM')
|
||||
net.writeFloat(self:getRPM() / self.maxRPM)
|
||||
net.send(self.vehicle.playersConnectedToHUD, true)
|
||||
|
||||
-- net.start('ENGINE_FULLRPM')
|
||||
-- net.writeUInt(self:getRPM(), 16)
|
||||
-- net.writeFloat(self.masterThrottle)
|
||||
-- net.send(nil, true)
|
||||
net.start('ENGINE_FULLRPM')
|
||||
net.writeUInt(self:getRPM(), 16)
|
||||
net.writeFloat(self.masterThrottle)
|
||||
net.send(nil, true)
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
---@type fun(vehicle: KPTLVehicle, name?: string, config?: EngineConfig): Engine
|
||||
Engine.new = Engine.new
|
||||
|
||||
return Engine
|
||||
|
||||
@@ -129,4 +129,7 @@ function PowertrainComponent:serializeDebugData() end
|
||||
---@return nil
|
||||
function PowertrainComponent:deserializeDebugData(result) end
|
||||
|
||||
---@type fun(vehicle: KPTLVehicle, name?: string, config?: PowertrainComponentConfig): PowertrainComponent
|
||||
PowertrainComponent.new = PowertrainComponent.new
|
||||
|
||||
return PowertrainComponent
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
--@include /koptilnya/libs/constants.txt
|
||||
--@include /koptilnya/libs/entity.txt
|
||||
|
||||
---@type PowertrainComponent
|
||||
local PowertrainComponent = require('./powertrain_component.txt')
|
||||
|
||||
---@type CustomWheel
|
||||
local CustomWheel = require('../wheel/wheel.txt')
|
||||
|
||||
require('/koptilnya/libs/constants.txt')
|
||||
@@ -18,13 +21,11 @@ require('/koptilnya/libs/entity.txt')
|
||||
---@field CustomWheel? CustomWheelConfig
|
||||
|
||||
---@class Wheel: PowertrainComponent
|
||||
---@field entity Entity
|
||||
---@field brakePower number
|
||||
---@field handbrakePower number
|
||||
---@field direction integer
|
||||
---@field private rot number
|
||||
---@field model string
|
||||
---@field holo Hologram | Entity
|
||||
---@field customWheel CustomWheel
|
||||
local Wheel = class('Wheel', PowertrainComponent)
|
||||
|
||||
@@ -55,11 +56,11 @@ function Wheel:initialize(vehicle, name, config)
|
||||
render.setMaterial(mat)
|
||||
render.setColor(Color(255, 0, 0, 200))
|
||||
lerpForwardFrictionForce = math.lerp(0.1, lerpForwardFrictionForce, self.DEBUG_DATA.forwardFrictionForce)
|
||||
render.draw3DBeam(pos, pos + ((lerpForwardFrictionForce / 500 + 16) * self.DEBUG_DATA.forward), 1, 0, 0)
|
||||
render.draw3DBeam(pos, pos + ((lerpForwardFrictionForce / 500 + 0) * self.DEBUG_DATA.forward), 1, 0, 0)
|
||||
|
||||
render.setColor(Color(0, 255, 0, 255))
|
||||
lerpSideFrictionForce = math.lerp(0.1, lerpSideFrictionForce, self.DEBUG_DATA.sideFrictionForce)
|
||||
render.draw3DBeam(pos, pos + ((lerpSideFrictionForce / 500 + 16) * self.DEBUG_DATA.right), 1, 0, 0)
|
||||
render.draw3DBeam(pos, pos + ((lerpSideFrictionForce / 500 + 0) * self.DEBUG_DATA.right), 1, 0, 0)
|
||||
|
||||
render.setColor(Color(0, 0, 255, 200))
|
||||
lerpLoad = math.lerp(0.1, lerpLoad, self.DEBUG_DATA.load)
|
||||
@@ -72,7 +73,6 @@ function Wheel:initialize(vehicle, name, config)
|
||||
return
|
||||
end
|
||||
|
||||
self.entity = config.Entity or NULL_ENTITY
|
||||
self.brakePower = config.BrakePower or 0
|
||||
self.handbrakePower = config.HandbrakePower or 0
|
||||
self.model = config.Model or ''
|
||||
@@ -84,33 +84,52 @@ function Wheel:initialize(vehicle, name, config)
|
||||
}
|
||||
self.wireOutputs = {
|
||||
[string.format('%s_RPM', self.name)] = 'number',
|
||||
[string.format('%s_Fx', self.name)] = 'number',
|
||||
[string.format('%s_CTq', self.name)] = 'number',
|
||||
}
|
||||
|
||||
self.rot = 0
|
||||
|
||||
self.holo = self:createHolo(self.entity)
|
||||
---@type Entity?
|
||||
self.entity = nil
|
||||
|
||||
self.customWheel = CustomWheel:new(table.merge(table.copy(config.CustomWheel), { Direction = self.direction, Name = self.name }))
|
||||
---@type Hologram?
|
||||
self.holo = nil
|
||||
|
||||
self.customWheel = CustomWheel:new(
|
||||
table.merge(
|
||||
table.copy(config.CustomWheel),
|
||||
{ Direction = self.direction, Name = self.name, ParentPhysObj = vehicle.basePhysObject }
|
||||
)
|
||||
)
|
||||
|
||||
hook.add('Input', 'vehicle_wheel_update' .. self.name, function(name, value)
|
||||
if name == self.name then
|
||||
self.entity = value
|
||||
self.customWheel:setEntity(value)
|
||||
|
||||
if isValid(self.holo) then
|
||||
self.holo:remove()
|
||||
end
|
||||
|
||||
self.holo = self:createHolo(self.entity)
|
||||
self.customWheel.radius = self:getEntityRadius()
|
||||
self:setEntity(value)
|
||||
end
|
||||
end)
|
||||
|
||||
self.steerVelocity = 0
|
||||
end
|
||||
|
||||
---@override
|
||||
---@return nil
|
||||
function Wheel:onWirePortsReady()
|
||||
self:setEntity(self.CONFIG.Entity or wire.ports[self.name])
|
||||
end
|
||||
|
||||
---@private
|
||||
---@param entity Entity
|
||||
---@return nil
|
||||
function Wheel:setEntity(entity)
|
||||
self.entity = entity
|
||||
self.customWheel:setEntity(entity)
|
||||
self.customWheel.radius = self:getEntityRadius()
|
||||
|
||||
if isValid(self.holo) then
|
||||
self.holo:remove()
|
||||
end
|
||||
|
||||
self.holo = self:createHolo(self.entity)
|
||||
end
|
||||
|
||||
---@return number
|
||||
function Wheel:getEntityRadius()
|
||||
if not isValid(self.entity) then
|
||||
return 0
|
||||
@@ -119,16 +138,16 @@ function Wheel:getEntityRadius()
|
||||
return self.entity:getModelRadius() * UNITS_TO_METERS
|
||||
end
|
||||
|
||||
---@return Hologram | Entity
|
||||
---@return Hologram?
|
||||
function Wheel:createHolo(entity)
|
||||
if not isValid(entity) then
|
||||
return NULL_ENTITY
|
||||
return nil
|
||||
end
|
||||
|
||||
local holo = hologram.create(entity:getPos(), entity:getAngles(), self.model or '')
|
||||
|
||||
if holo == nil or isValid(holo) then
|
||||
return NULL_ENTITY
|
||||
if holo == nil or not isValid(holo) then
|
||||
return nil
|
||||
end
|
||||
|
||||
holo:setParent(entity)
|
||||
@@ -143,8 +162,6 @@ function Wheel:updateWireOutputs()
|
||||
PowertrainComponent.updateWireOutputs(self)
|
||||
|
||||
wire.ports[string.format('%s_RPM', self.name)] = self.customWheel:getRPM()
|
||||
wire.ports[string.format('%s_Fx', self.name)] = self.customWheel.forwardFriction.force
|
||||
wire.ports[string.format('%s_CTq', self.name)] = self.customWheel.counterTorque
|
||||
end
|
||||
|
||||
---@return number
|
||||
@@ -153,8 +170,10 @@ function Wheel:queryInertia()
|
||||
end
|
||||
|
||||
---@return number
|
||||
function Wheel:queryAngularVelocity()
|
||||
return self.angularVelocity
|
||||
function Wheel:queryAngularVelocity(angularVelocity)
|
||||
self.customWheel.angularVelocity = angularVelocity
|
||||
|
||||
return self.customWheel.angularVelocity
|
||||
end
|
||||
|
||||
---@param torque number
|
||||
@@ -228,4 +247,7 @@ function Wheel:deserializeDebugData(result)
|
||||
result.sideFrictionForce = net.readFloat()
|
||||
end
|
||||
|
||||
---@type fun(vehicle: KPTLVehicle, name?: string, config?: WheelConfig): Wheel
|
||||
Wheel.new = Wheel.new
|
||||
|
||||
return Wheel
|
||||
|
||||
Reference in New Issue
Block a user