概要
robloxでassistantやってみた。
練習問題やってみた。
練習問題
PID制御で倒れる壁を立たせよ。
手順
- ServerScriptServiceに、scriptを追加。
- スクリプトを書く。
local PID = {}
PID.__index = PID
function PID.new(min: number, max: number, kp: number, ki: number, kd: number)
local self = setmetatable({}, PID)
self._min = min
self._max = max
self._kp = kp
self._ki = ki
self._kd = kd
self._lastInput = 0
self._outputSum = 0
self.POnE = true
return self
end
function PID:Reset()
self._lastInput = 0
self._outputSum = 0
end
function PID:Calculate(setpoint: number, input: number)
local err = (setpoint - input)
local dInput = (input - self._lastInput)
self._outputSum += (self._ki * err)
if not self.POnE then
self._outputSum -= self._kp * dInput
end
self._outputSum = math.clamp(self._outputSum, self._min, self._max)
local output = 0
if self.POnE then
output = self._kp * err
end
output += self._outputSum - self._kd * dInput
output = math.clamp(output, self._min, self._max)
self._lastInput = input
return output
end
function PID:Debug(name: string, parent: Instance?)
if self._debug then
return
end
if not game:GetService("RunService"):IsStudio() then
return
end
local folder = Instance.new("Folder")
folder.Name = name
local function Bind(attrName, propName)
folder:SetAttribute(attrName, self[propName])
folder:GetAttributeChangedSignal(attrName):Connect(function()
self[propName] = folder:GetAttribute(attrName)
self:Reset()
end)
end
Bind("Min", "_min")
Bind("Max", "_max")
Bind("KP", "_kp")
Bind("KI", "_ki")
Bind("KD", "_kd")
folder.Parent = parent or workspace
self._debug = folder
end
function PID:Destroy()
if self._debug then
self._debug:Destroy()
self._debug = nil
end
end
local part = Instance.new("Part", workspace)
part.Size = Vector3.new(0.5, 9, 5)
part.CFrame = CFrame.new(0, 6, 0)
local pid = PID.new(-1000, 1000, 100, 10, 5)
local attachment = Instance.new("Attachment", part)
local vectorForce = Instance.new("VectorForce", part)
vectorForce.Attachment0 = attachment
local function update(deltaTime: number)
local tilt = part.Orientation.X
local force = pid:Calculate(0, tilt)
vectorForce.Force = Vector3.new(force, 0, 0)
end
game:GetService("RunService").Stepped:Connect(update)
写真
以上。