--[[ diag_steer5.luau -- find a FIX for the servo/motor conflict. Established by diag_steer4: an ENABLED WheelMotor hinge locks the knuckle so the steer servo cannot yaw it. Disabling the motor (or deleting the wheel) restores perfect tracking (-19.99 of -20.0). MotorMaxTorque is 0 at build time, so this is NOT a torque contest -- it is a degenerate constraint configuration. Suspicion: Hub, Knuckle and Wheel are all built at the SAME CFrame, and the motor's two attachments are both identity CFrames, so every attachment sits at the same world point. Two hinges sharing a point with perpendicular axes is ill-conditioned for the solver. Each variant below changes ONE thing and re-measures. ]] local ServerScriptService = game:GetService("ServerScriptService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local RunService = game:GetService("RunService") local out = {} local function log(...) local parts = {} for i = 1, select("#", ...) do parts[#parts + 1] = tostring((select(i, ...))) end table.insert(out, table.concat(parts, " ")) end local Shared = ReplicatedStorage:FindFirstChild("Shared") local Cars = require(Shared.Cars) local Chassis = require(Shared.Chassis) local Server = ServerScriptService:FindFirstChild("Server", true) local CarManager = require(Server.CarManager) local pad = Instance.new("Part") pad.Size = Vector3.new(3000, 8, 3000) pad.Position = Vector3.new(0, 5000, 0) pad.Anchored = true pad.Material = Enum.Material.Concrete pad.Parent = workspace local padTop = pad.Position.Y + 4 local car = Cars.Get("gtr_r34") local tuning = Chassis.tuningFor(car) local TARGET = -20 local function parts(model) local servos, motors, wheels, knuckles = {}, {}, {}, {} for _, d in ipairs(model:GetDescendants()) do if d:IsA("HingeConstraint") then if d.Name == Chassis.STEER_SERVO_NAME then table.insert(servos, d) elseif d.Name == Chassis.WHEEL_MOTOR_NAME then table.insert(motors, d) end elseif d:IsA("BasePart") then if d.Name:sub(1, 6) == "Wheel_" then table.insert(wheels, d) elseif d.Name:sub(1, 8) == "Knuckle_" then table.insert(knuckles, d) end end end return servos, motors, wheels, knuckles end -- mutate: applied after build, before settling. drive: applied after settling. local function variant(label, mutate, drive) local m = CarManager._buildForDiag(car, tuning) m.Parent = workspace m:PivotTo(CFrame.new(0, padTop + 3, 0)) local servos, motors, wheels, knuckles = parts(m) if mutate then mutate(servos, motors, wheels, knuckles, m) end for _ = 1, 60 do RunService.Heartbeat:Wait() end local body = m.PrimaryPart body.AssemblyLinearVelocity = body.CFrame.LookVector * 80 if drive then drive(servos, motors, wheels, knuckles, m) end for _, s in ipairs(servos) do s.TargetAngle = TARGET end local trace, yaw = {}, {} for step = 1, 120 do for _, s in ipairs(servos) do s.TargetAngle = TARGET end if step % 24 == 0 then trace[#trace + 1] = string.format("%.1f", servos[1].CurrentAngle) yaw[#yaw + 1] = string.format("%.2f", body.AssemblyAngularVelocity.Y) end RunService.Heartbeat:Wait() end local final = servos[1].CurrentAngle local ok = math.abs(final - TARGET) < 5 log( string.format( "%-40s [%s] final %6.2f yaw[%s] %s", label, table.concat(trace, " "), final, table.concat(yaw, " "), ok and "*** STEERS ***" or "stuck" ) ) m:Destroy() end log(string.format("target %.1f deg, rolling at 80 studs/s, motors at build-default torque", TARGET)) log("") variant("V0 baseline (unmodified)", nil, nil) variant("V1 motor ActuatorType = None", function(_, motors) for _, mo in ipairs(motors) do mo.ActuatorType = Enum.ActuatorType.None end end) variant("V2 motor attachments offset 0.01 X", function(_, motors) for _, mo in ipairs(motors) do mo.Attachment0.CFrame = mo.Attachment0.CFrame * CFrame.new(0.01, 0, 0) end end) variant("V3 knuckle mass x20 (density)", function(_, _, _, knuckles) for _, k in ipairs(knuckles) do k.CustomPhysicalProperties = PhysicalProperties.new(20, 0.3, 0.5, 1, 1) end end) variant("V4 wheel Massless=true", function(_, _, wheels) for _, w in ipairs(wheels) do w.Massless = true end end) variant("V5 servo torque 1e9 + speed 30", function(servos) for _, s in ipairs(servos) do s.ServoMaxTorque = 1e9 s.AngularSpeed = 30 end end) variant("V6 motor torque 0 held every frame", nil, function(_, motors) for _, mo in ipairs(motors) do mo.MotorMaxTorque = 0 mo.AngularVelocity = 0 end end) variant("V7 front motors disabled only", function(_, motors) -- rear-wheel drive: only the steered corners freewheel for _, mo in ipairs(motors) do local n = mo.Parent and mo.Parent.Name or "" if n:find("F") then mo.Enabled = false end end end) variant("V8 V1 + V5 combined", function(servos, motors) for _, mo in ipairs(motors) do mo.ActuatorType = Enum.ActuatorType.None end for _, s in ipairs(servos) do s.ServoMaxTorque = 1e9 s.AngularSpeed = 30 end end) pad:Destroy() return table.concat(out, "\n")