This commit is contained in:
Никита Круглицкий 2025-05-11 02:18:55 +06:00
parent 9f19c7d618
commit 14ab069846
5 changed files with 124 additions and 99 deletions

View File

@ -10,9 +10,9 @@ local Differential = require('/koptilnya/engine_remastered/powertrain/differenti
local WheelConfig = {
BrakePower = 1200,
CustomWheel = { Mass = 80 },
Model = 'models/sprops/trans/wheel_d/t_wheel25.mdl'
Model = 'models/sprops/trans/wheel_a/wheel25.mdl'
}
local FrontWheelsConfig = table.merge(table.copy(WheelConfig), { SteerLock = 33, CustomWheel = { Mass = 80, CasterAngle = 7 } })
local FrontWheelsConfig = table.merge(table.copy(WheelConfig), { SteerLock = 33, CustomWheel = { CasterAngle = 3 } })
local RearWheelsConfig = table.merge(table.copy(WheelConfig), { HandbrakePower = 2200 })
Vehicle:new({
@ -21,7 +21,7 @@ Vehicle:new({
Type = POWERTRAIN_COMPONENT.Engine,
Config = {
IdleRPM = 900,
MaxRPM = 7500,
MaxRPM = 7000,
Inertia = 0.151,
StartFriction = -10,
FrictionCoeff = 0.01,
@ -59,48 +59,72 @@ Vehicle:new({
},
{
Name = 'AxleFront',
Type = POWERTRAIN_COMPONENT.Differential,
Config = {
SteerLock = 50
}
},
{
Name = 'WheelFL',
Type = POWERTRAIN_COMPONENT.Wheel,
Input = 'AxleFront',
Config = table.merge(table.copy(FrontWheelsConfig), { Offset = 0 })
},
{
Name = 'WheelFR',
Type = POWERTRAIN_COMPONENT.Wheel,
Input = 'AxleFront',
Config = table.merge(table.copy(FrontWheelsConfig), { Offset = 180 })
},
{
Name = 'Axle1',
Input = 'Gearbox',
Input = 'Axle',
Type = POWERTRAIN_COMPONENT.Differential,
Config = {
Type = Differential.TYPES.Open,
FinalDrive = 3.392,
Inertia = 0.01,
BiasAB = 0.5,
CoastRamp = 0.5,
CoastRamp = 1,
PowerRamp = 1,
Stiffness = 0.1,
SlipTorque = 1000
SlipTorque = 0,
SteerLock = 45
}
},
{
Name = 'WheelFL',
Type = POWERTRAIN_COMPONENT.Wheel,
Input = 'AxleFront',
Config = table.merge(table.copy(FrontWheelsConfig), { Offset = 0, CustomWheel = { CamberAngle = -3, ToeAngle = -0.5 } })
},
{
Name = 'WheelFR',
Type = POWERTRAIN_COMPONENT.Wheel,
Input = 'AxleFront',
Config = table.merge(table.copy(FrontWheelsConfig), { Offset = 180, CustomWheel = { CamberAngle = 3, ToeAngle = 0.5 } })
},
{
Name = 'AxleBack',
Input = 'Axle',
Type = POWERTRAIN_COMPONENT.Differential,
Config = {
Type = Differential.TYPES.Open,
FinalDrive = 3.392,
Inertia = 0.01,
BiasAB = 0.5,
CoastRamp = 1,
PowerRamp = 1,
Stiffness = 0.1,
SlipTorque = 0
}
},
{
Name = 'Axle',
Input = 'Gearbox',
Type = POWERTRAIN_COMPONENT.Differential,
Config = {
Type = Differential.TYPES.Open,
FinalDrive = 1,
Inertia = 0.01,
BiasAB = 0.5,
CoastRamp = 1,
PowerRamp = 1,
Stiffness = 0.1,
SlipTorque = 0
}
},
{
Name = 'WheelRL',
Input = 'Axle1',
Input = 'AxleBack',
Type = POWERTRAIN_COMPONENT.Wheel,
Config = table.merge(table.copy(RearWheelsConfig), { Offset = 0 })
Config = table.merge(table.copy(RearWheelsConfig), { Offset = 0, CustomWheel = { CamberAngle = -1, ToeAngle = -0.5 } })
},
{
Name = 'WheelRR',
Input = 'Axle1',
Input = 'AxleBack',
Type = POWERTRAIN_COMPONENT.Wheel,
Config = table.merge(table.copy(RearWheelsConfig), { Offset = 180 })
Config = table.merge(table.copy(RearWheelsConfig), { Offset = 180, CustomWheel = { CamberAngle = 1, ToeAngle = 0.5 } })
}
})

View File

@ -131,7 +131,6 @@ function Differential:forwardStep(torque, inertia)
self.steerLock
)
-- Аккерман
local wheelbase = 2.05
local trackWidth = 1.124
local radius = wheelbase / math.tan(math.rad(self.steerAngle))

View File

@ -11,6 +11,8 @@ require('/koptilnya/libs/entity.txt')
local Wheel = class('Wheel', PowertrainComponent)
local DEBUG = false
function Wheel:initialize(vehicle, name, config)
PowertrainComponent.initialize(self, vehicle, name, config)
@ -30,7 +32,6 @@ function Wheel:initialize(vehicle, name, config)
}
self.rot = 0
self.offset = config.Offset or 0
self.entity = config.Entity or NULL_ENTITY
@ -49,28 +50,35 @@ function Wheel:initialize(vehicle, name, config)
self.holo = self:createHolo(self.entity)
if DEBUG then
self.debugHoloF:setPos(self.entity:getPos())
self.debugHoloR:setPos(self.entity:getPos())
self.debugHoloU:setPos(self.entity:getPos())
self.debugHoloF:setParent(self.entity)
self.debugHoloR:setParent(self.entity)
self.debugHoloU:setParent(self.entity)
end
if not config.Radius then
self.customWheel.radius = self:getEntityRadius()
end
end
end)
local right = self.entity:getRight():getRotated(Angle(0, 90, 0))
local offsetRight = self.entity:getRight():rotateAroundAxis(self.entity:getUp(), self.offset)
if DEBUG then
self.debugHoloF = holograms.create(Vector(), Angle(), 'models/sprops/rectangles_thin/size_0/rect_1_5x48x1_5.mdl')
self.debugHoloR = holograms.create(Vector(), Angle(), 'models/sprops/rectangles_thin/size_0/rect_1_5x48x1_5.mdl')
self.debugHoloU = holograms.create(Vector(), Angle(), 'models/sprops/rectangles_thin/size_0/rect_1_5x48x1_5.mdl')
self.dir = right:dot(offsetRight)
self.debugHoloF:setMaterial('models/debug/debugwhite')
self.debugHoloR:setMaterial('models/debug/debugwhite')
self.debugHoloU:setMaterial('models/debug/debugwhite')
self.debugHolo1 = holograms.create(
Vector(),
Angle(),
'models/sprops/geometry/sphere_3.mdl'
)
self.debugHolo2 = holograms.create(
Vector(),
Angle(),
'models/sprops/geometry/sphere_3.mdl'
)
self.debugHoloF:setColor(Color(255, 0, 0))
self.debugHoloR:setColor(Color(0, 255, 0))
self.debugHoloU:setColor(Color(0, 0, 255))
end
self.steerVelocity = 0
end
@ -90,13 +98,12 @@ function Wheel:createHolo(entity)
local holo = holograms.create(
entity:getPos(),
entity:getAngles() + Angle(0, self.offset, 0),
entity:getAngles(),
self.CONFIG.Model or ''
)
holo:setParent(entity)
-- holo:setColor(Color(255,255,255,110))
entity:setColor(Color(0,0,0,0))
return holo
@ -121,9 +128,9 @@ function Wheel:forwardStep(torque, inertia)
return 0
end
-- self.customWheel.steerAngle = self.vehicle.steer * self.steerLock
--self.customWheel.inertia = inertia
--self.customWheel:setInertia(inertia)
-- print(inertia)
-- self.customWheel:setInertia(inertia)
self.customWheel.motorTorque = torque
self.customWheel.brakeTorque = math.max(self.brakePower * self.vehicle.brake, self.handbrakePower * self.vehicle.handbrake)
@ -131,8 +138,6 @@ function Wheel:forwardStep(torque, inertia)
self.angularVelocity = self.customWheel.angularVelocity
self.debugHolo1:setPos(self.entity:localToWorld(Vector(0, 0, -self.entity:getModelRadius())))
if self.customWheel.hasHit and isValid(self.vehicle.basePhysObject) then
local surfaceForceVector = self.customWheel.right * self.customWheel.sideFriction.force + self.customWheel.forward * self.customWheel.forwardFriction.force
@ -140,30 +145,21 @@ function Wheel:forwardStep(torque, inertia)
end
if isValid(self.holo) then
if DEBUG then
self.debugHoloF:setAngles(self.customWheel.forward:getAngle())
self.debugHoloR:setAngles(self.customWheel.right:getAngle())
self.debugHoloU:setAngles(self.customWheel.up:getAngle())
end
local spinAxis = self.customWheel.up:cross(self.customWheel.forward):getNormalized()
local entityAngles = self.entity:getAngles()
self.debugHolo2:setPos(self.entity:localToWorld(self.customWheel.up * math.sin(timer.curtime()) * 20))
self.rot = self.rot + self.angularVelocity * TICK_INTERVAL
local rotatedForwardAngle = self.customWheel.forward:getAngle() + Angle(0, 90, 0)
local steerRotated = entityAngles:rotateAroundAxis(self.customWheel.up, nil, math.rad(-self.customWheel.steerAngle) + self.customWheel.toeAngle)
local camberRotated = steerRotated:rotateAroundAxis(self.customWheel.forward, nil, -self.customWheel.camberAngle)
local angularVelocityRotated = camberRotated:rotateAroundAxis(self.customWheel.right, nil, self.rot)
-- self.holo:setAngles(rotatedForwardAngle)
-- local ang = up:getAngle()
-- self.holo:setAngles(self.customWheel.forward:getAngle())
-- self.holo:setAngles(self.holo:getAngles():rotateAroundAxis(self.customWheel.right, 0))
-- self.holo:setAngles(self.holo:getAngles():rotateAroundAxis(self.customWheel.right, nil, self.angularVelocity * TICK_INTERVAL))
self.holo:setAngles(self.holo:getAngles():rotateAroundAxis(self.customWheel.right, nil, self.angularVelocity * TICK_INTERVAL))
-- local steerAngle = self.entity:localToWorldAngles(Angle(0, self.offset - self.customWheel.steerAngle, 0) + self.rotationAxle * self.rot)
-- local angle = steerAngle
-- self.holo:setAngles(angle)
self.holo:setAngles(angularVelocityRotated)
end
return self.customWheel.counterTorque

View File

@ -3,10 +3,10 @@ local FrictionPreset = class('FrictionPreset')
function FrictionPreset:initialize(config)
config = config or {}
self.B = config.B or 10.86
self.C = config.C or 2.15
self.D = config.D or 0.933
self.E = config.E or 0.992
self.B = config.B or 11
self.C = config.C or 1.15
self.D = config.D or 1.03
self.E = config.E or -10
end
function FrictionPreset:evaluate(slip)

View File

@ -18,11 +18,13 @@ function Wheel:initialize(config)
self.squat = config.Squat or 0.1
self.slipCircleShape = config.SlipCircleShape or 1.05
self.casterAngle = math.rad(config.CasterAngle or 0)
self.camberAngle = math.rad(config.CamberAngle or 0)
self.toeAngle = math.rad(config.ToeAngle or 0)
self.forwardFriction = Friction:new(config.ForwardFriction)
self.sideFriction = Friction:new(config.SideFriction)
self.frictionPreset = FrictionPreset:new(config.FrictionPreset)
self.satFrictionPreset = FrictionPreset:new({ B = 13, C = 2.4, D = 1, E = 0.48 })
self.satFrictionPreset = FrictionPreset:new()
self.motorTorque = 0
self.brakeTorque = 0
@ -60,6 +62,7 @@ end
function Wheel:setInertia(inertia)
if isValid(self.physObj) then
print(inertia)
self.physObj:setInertia(Vector(inertia))
self.inertia = inertia
end
@ -186,12 +189,28 @@ function Wheel:selfAligningTorque(Sy, load)
local effectiveTrail = mechanicalTrail + casterEffect * self.radius
local D_scaled = D * loadScale * effectiveTrail
local camberEffect = 1 + 0.5 * math.abs(self.camberAngle)
local toeEffect = 1 + 0.3 * math.abs(self.toeAngle)
local term = B * Sy - E * (B * Sy - math.atan(B * Sy))
local Mz = D_scaled * math.sin(C * math.atan(term))
local Mz = D_scaled * camberEffect * toeEffect * math.sin(C * math.atan(term))
return Mz
end
function Wheel:rotateVector(vector)
local ang = self.entity:getAngles()
local baseForward = ang:getForward()
local baseUp = ang:getUp()
local baseRight = -ang:getRight()
local steerRotated = vector:rotateAroundAxis(baseUp, nil, math.rad(-self.steerAngle) + self.toeAngle)
local camberRotated = steerRotated:rotateAroundAxis(baseForward, nil, -self.camberAngle)
local casterRotated = camberRotated:rotateAroundAxis(baseRight, nil, -self.casterAngle)
return casterRotated:getNormalized()
end
function Wheel:update()
if not isValid(self.entity) or not isValid(self.physObj) then
return
@ -206,27 +225,14 @@ function Wheel:update()
self.longitudinalLoadCoefficient = self:getLongitudinalLoadCoefficient(self.load * 1000)
self.lateralLoadCoefficient = self:getLateralLoadCoefficient(self.load * 1000)
local baseForward = self.entity:getForward()
local baseUp = self.entity:getUp()
local baseRight = self.entity:getRight()
local ang = self.entity:getAngles()
local baseForward = ang:getForward()
local baseUp = ang:getUp()
local baseRight = -ang:getRight()
local steerRotatedForward = baseForward:rotateAroundAxis(baseUp, -self.steerAngle)
local finalForward = steerRotatedForward:rotateAroundAxis(baseRight, nil, self.casterAngle)
self.forward = finalForward:getNormalized()
self.right = baseUp:cross(self.forward):getNormalized()
self.up = self.forward:cross(self.right):getNormalized()
-- local steerRotated = self.entity:getForward():rotateAroundAxis(self.entity:getUp(), -self.steerAngle)
-- self.forward = steerRotated:rotateAroundAxis(self.entity:getRight(), self.casterAngle)
-- local steerRotatedRight = self.entity:getRight():rotateAroundAxis(self.entity:getUp(), -self.steerAngle)
-- self.right = steerRotatedRight:rotateAroundAxis(self.entity:getRight(), self.casterAngle)
-- self.forward = self.entity:getForward():rotateAroundAxis(self.entity:getUp(), -self.steerAngle)
-- self.right = self.entity:getRight():rotateAroundAxis(self.entity:getUp(), -self.steerAngle)
self.forward = self:rotateVector(baseForward)
self.right = self:rotateVector(baseRight)
self.up = self:rotateVector(baseUp)
local forwardSpeed = 0
local sideSpeed = 0