{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Chapter 6" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "using ControlSystems\n", "using Plots; gr()\n", "using LinearAlgebra" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ナイキストの安定判別" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "TransferFunction{Continuous, ControlSystems.SisoRational{Float64}}\n", " 1.0\n", "----------------------------\n", "1.0s^3 + 1.0s^2 + 1.5s + 1.0\n", "\n", "Continuous-time transfer function model\n", "ComplexF64[-0.12040192275078712 + 1.1413527165187305im, -0.12040192275078712 - 1.1413527165187305im, -0.7591961544984255 + 0.0im]\n" ] } ], "source": [ "P = tf([0, 1], [1, 1, 1.5, 1])\n", "println(P)\n", "println(pole(P))" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "P = tf([0,1],[1,1,1.5,1])\n", "# 位相が 180[deg] 遅れる周波数を取得\n", "wpc, _, _, _ = margin(P);\n", "\n", "t = 0:0.1:30;\n", "u = sin.(wpc[]*t);\n", "y = 0 .* u;\n", "\n", "p = [ plot() plot(); plot() plot() ]\n", "\n", "for i in [1,2]\n", " for j in [1,2]\n", " # 出力をネガティブフィードバックして次の時刻の入力を生成\n", " u = sin.(wpc[]*t) - vec(y)\n", " y, t, x, uout = lsim(P, u', t)\n", " plot!(p[i,j], t, u, label=\"u\");\n", " plot!(p[i,j], t, vec(y), label=\"y\");\n", " end\n", "end\n", "\n", "plot( p[1,1], p[1,2], p[2,1], p[2,2], layout=(2,2))" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "TransferFunction{Continuous, ControlSystems.SisoRational{Float64}}\n", " 1.0\n", "-------------------------------\n", "1.0s^3 + 2.0s^2 + 1.9999s + 1.0\n", "\n", "Continuous-time transfer function model\n", "ComplexF64[-1.0000999999990001 + 0.0im, -0.4999500000004993 + 0.8659965401198194im, -0.4999500000004993 - 0.8659965401198194im]\n" ] } ], "source": [ "P = tf([0, 1], [1, 2, 1.9999, 1])\n", "println(P)\n", "println(pole(P))" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "P = tf([0,1],[1,2,1.9999,1])\n", "# 位相が 180[deg] 遅れる周波数を取得\n", "wpc, _, _, _ = margin(P);\n", "\n", "t = 0:0.1:30;\n", "u = sin.(wpc[]*t);\n", "y = 0 .* u;\n", "\n", "p = [ plot() plot(); plot() plot() ]\n", "\n", "for i in [1,2]\n", " for j in [1,2]\n", " # 出力をネガティブフィードバックして次の時刻の入力を生成\n", " u = sin.(wpc[]*t) - vec(y)\n", " y, t, x, uout = lsim(P, u', t)\n", " plot!(p[i,j], t, u, label=\"u\");\n", " plot!(p[i,j], t, vec(y), label=\"y\");\n", " end\n", "end\n", "\n", "plot( p[1,1], p[1,2], p[2,1], p[2,2], layout=(2,2))" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 閉ループ系が不安定になる場合\n", "P = tf([0, 1],[1, 1, 1.5, 1])\n", "\n", "nyquistplot(P, gaincircle=true, lw = 2, xlims=(-2.5,2.5), ylims=(-2.5,2.5), size=(300,300))" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 閉ループ系が安定になる場合\n", "P = tf([0, 1],[1, 2, 1.9999, 1])\n", "\n", "nyquistplot(P, gaincircle=true, lw = 2, xlims=(-2.5,2.5), ylims=(-2.5,2.5), size=(300,300))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## アームの角度制御(PID制御)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "30" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g = 9.81 # 重力加速度[m/s^2]\n", "l = 0.2 # アームの長さ[m]\n", "M = 0.5 # アームの質量[kg]\n", "mu = 1.5e-2 # 粘性摩擦係数\n", "J = 1.0e-2 # 慣性モーメント\n", "\n", "P = tf( [0,1], [J, mu, M*g*l] )\n", "\n", "ref = 30 # 目標角度 [deg]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### P制御" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "kp = (0.5, 1, 2)\n", "\n", "H = [ P*tf([0, kp[i]], [0, 1]) for i = 1:length(kp) ]\n", "\n", "setPlotScale(\"dB\")\n", "bodeplot(H, lw=2, size=(450,400),\n", " label=[\"kₚ=$(kp[1])\" \"kₚ=$(kp[1])\" \"kₚ=$(kp[2])\" \"kₚ=$(kp[2])\" \"kₚ=$(kp[3])\" \"kₚ=$(kp[3])\"],\n", " legend=:best, title=\"\" )" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "kP=0.5\n", "(wpc, GM, wgc, PM)\n", "([NaN;;], [Inf;;], [12.048359830388655;;], [21.007168728281016;;])\n", "-----------------\n", "kP=1\n", "(wpc, GM, wgc, PM)\n", "([NaN;;], [Inf;;], [14.00755547266918;;], [12.0877310471827;;])\n", "-----------------\n", "kP=2\n", "(wpc, GM, wgc, PM)\n", "([NaN;;], [Inf;;], [17.231985129715717;;], [7.406517464524029;;])\n", "-----------------\n" ] } ], "source": [ "for i in 1:length(kp)\n", " K = tf([0, kp[i]], [0, 1]) # P制御\n", " H = P * K # 開ループ系\n", " \n", " println(\"kP=\", kp[i])\n", " println(\"(wpc, GM, wgc, PM)\")\n", " println(margin(H))\n", " println(\"-----------------\")\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### PI制御" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "kp = 2\n", "ki = (0, 5, 10)\n", "\n", "H = [ P*tf([kp, ki[i]], [1, 0]) for i = 1:length(ki) ]\n", "\n", "setPlotScale(\"dB\")\n", "bodeplot(H, lw=2, size=(450,400),\n", " label=[\"ki=$(ki[1])\" \"ki=$(ki[1])\" \"ki=$(ki[2])\" \"ki=$(ki[2])\" \"ki=$(ki[3])\" \"ki=$(ki[3])\"],\n", " legend=:best, title=\"\" )" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "kI=0\n", "(wpc, GM, wgc, PM)\n", "([NaN;;], [Inf;;], [17.231985129715717;;], [7.406517464524029;;])\n", "-----------------\n", "kI=5\n", "(wpc, GM, wgc, PM)\n", "([15.671318145841404;;], [0.7374341834142752;;], [17.29090924820676;;], [0.8699461934346004;;])\n", "-----------------\n", "kI=10\n", "(wpc, GM, wgc, PM)\n", "([11.849199557862834;;], [0.2113800049851713;;], [17.452928304499043;;], [8.761143190659993;;])\n", "-----------------\n" ] } ], "source": [ "for i in 1:length(ki)\n", " K = tf([kp, ki[i]], [1, 0]) # PI制御\n", " H = P * K # 開ループ系\n", " \n", " println(\"kI=\", ki[i])\n", " println(\"(wpc, GM, wgc, PM)\")\n", " println(margin(H))\n", " println(\"-----------------\")\n", "end" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plt = plot()\n", "\n", "for i in 1:1:length(ki)\n", " K = tf([kp, ki[i]], [1, 0]) # PI制御\n", " Gyr = feedback(P*K,1) # 閉ループ系\n", " y, t = step( Gyr, 0:0.01:2 )\n", " plot!(plt, t, ref*y',\n", " xlabel=\"t\", #X軸のラベル\n", " ylabel=\"y\", #Y軸のラベル\n", " lw=2, #線幅\n", " ls=:solid, #線種\n", " label=\"kI=$(ki[i])\",\n", " legend=:bottomright,\n", " size=(300,230) #プロットのサイズ \n", " )\n", "end\n", " \n", "plot(plt)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### PID制御" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "kp = 2\n", "ki = 5\n", "kd = (0, 0.1, 0.2)\n", "\n", "H = [ P*tf([kd[i], kp, ki], [1,0]) for i = 1:length(kd) ]\n", "\n", "setPlotScale(\"dB\")\n", "bodeplot(H, lw=2, size=(450,400),\n", " label=[\"kd=$(kd[1])\" \"kd=$(kd[1])\" \"kd=$(kd[2])\" \"kd=$(kd[2])\" \"kd=$(kd[3])\" \"kd=$(kd[3])\"],\n", " legend=:best, title=\"\" )" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "kD=0\n", "(wpc, GM, wgc, PM)\n", "([15.671318145841404;;], [0.7374341834142752;;], [17.29090924820676;;], [0.8699461934346004;;])\n", "-----------------\n", "kD=0.1\n", "(wpc, GM, wgc, PM)\n", "([NaN;;], [Inf;;], [18.809759446133874;;], [45.220116699008315;;])\n", "-----------------\n", "kD=0.2\n", "(wpc, GM, wgc, PM)\n", "([NaN;;], [Inf;;], [24.730502425798765;;], [71.27203690036902;;])\n", "-----------------\n" ] } ], "source": [ "for i in 1:length(kd)\n", " K = tf([kd[i], kp, ki], [1,0]) # PID制御\n", " H = P * K # 開ループ系\n", " \n", " println(\"kD=\", kd[i])\n", " println(\"(wpc, GM, wgc, PM)\")\n", " println(margin(H))\n", " println(\"-----------------\")\n", "end" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plt = plot()\n", "\n", "for i in 1:1:length(kd)\n", " K = tf([kd[i],kp,ki],[1,0]) # PID制御\n", " Gyr = feedback(P*K,1) # 閉ループ系\n", " y, t = step( Gyr, 0:0.01:2 )\n", " plot!(plt, t, ref*y',\n", " xlabel=\"t\", #X軸のラベル\n", " ylabel=\"y\", #Y軸のラベル\n", " lw=2, #線幅\n", " ls=:solid, #線種\n", " label=\"kD=$(kd[i])\",\n", " legend=:bottomright,\n", " size=(300,230) #プロットのサイズ \n", " )\n", "end\n", " \n", "plot(plt)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "開ループ系の比較" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "kp = (2, 1)\n", "ki = (5, 0)\n", "kd = (0.1, 0)\n", "Label = (\"After\", \"Before\")\n", "\n", "H = [ P*tf([kd[i], kp[i], ki[i]], [1,0]) for i = 1:length(kp) ]\n", "\n", "setPlotScale(\"dB\")\n", "bodeplot(H, lw=2, size=(450,400), \n", " label=[\"After\" \"After\" \"Before\" \"Before\"] , title=\"\" )" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "kP=2, kI=5, kD=0.1(wpc, GM, wgc, PM)\n", "([NaN;;], [Inf;;], [18.809759446133874;;], [45.220116699008315;;])\n", "-----------------\n", "kP=1, kI=0, kD=0(wpc, GM, wgc, PM)\n", "([NaN;;], [Inf;;], [14.00755547266918;;], [12.0877310471827;;])\n", "-----------------\n" ] } ], "source": [ "for i in 1:length(kp)\n", " K = tf([kd[i], kp[i], ki[i]], [1,0]) # PID制御\n", " H = P * K # 開ループ系\n", " \n", " print(\"kP=\", kp[i], \", kI=\", ki[i], \", kD=\", kd[i])\n", " println(\"(wpc, GM, wgc, PM)\")\n", " println(margin(H))\n", " println(\"-----------------\")\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "閉ループ系の比較" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "After\n", "定常偏差 =2.220446049250313e-16\n", "------------------\n", "Before\n", "定常偏差 =0.49520444220090865\n", "------------------\n" ] }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "kp = (2, 1)\n", "ki = (5, 0)\n", "kd = (0.1, 0)\n", "Label = (\"After\", \"Before\")\n", "\n", "plt = plot()\n", "\n", "for i in 1:1:length(kd)\n", " K = tf( [kd[i], kp[i], ki[i]], [1, 0])\n", " Gyr = feedback(P*K, 1)\n", " Gyr = minreal(Gyr)\n", " y, t = step( Gyr, 0:0.01:2 )\n", " plot!(plt, t, y',\n", " xlabel=\"t\", #X軸のラベル\n", " ylabel=\"y\", #Y軸のラベル\n", " lw=2, #線幅\n", " ls=:solid, #線種\n", " label=\"$(Label[i])\",\n", " legend=:bottomright,\n", " size=(300,230) #プロットのサイズ \n", " )\n", " \n", " println(Label[i])\n", " e_std = ( 1 - dcgain(Gyr)[])\n", " println(\"定常偏差 =\", e_std) \n", " println(\"------------------\")\n", "end\n", "\n", "plot(plt)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "H = [ P*tf([kd[i], kp[i], ki[i]], [1,0]) for i = 1:length(kp) ]\n", "Gyr = [ H[i]/(1+H[i]) for i = 1:length(kp) ]\n", "\n", "setPlotScale(\"dB\")\n", "bodeplot(Gyr, lw=2, size=(450,400),\n", " label=[\"After\" \"After\" \"Before\" \"Before\"] , title=\"\" )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 位相遅れ・進み補償" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 位相遅れ" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "TransferFunction{Continuous, ControlSystems.SisoRational{Float64}}\n", "1.0s + 10.0\n", "-----------\n", "1.0s + 1.0\n", "\n", "Continuous-time transfer function model" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "α = 10\n", "T1 = 0.1\n", "K1 = tf([α *T1, α ], [α *T1, 1])" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "setPlotScale(\"dB\")\n", "bodeplot(K1, lw=2, size=(450,400), legend=false, title=\"\" )" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ωₘ=3.162277660168379\n", "ϕₘ=-54.90319877241541\n" ] } ], "source": [ "ωₘ = 1/T1/√α\n", "ϕₘ = asin( (1-α)/(1+α ) ) * 180/π\n", "println(\"ωₘ=\", ωₘ)\n", "println(\"ϕₘ=\", ϕₘ)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "TransferFunction{Continuous, ControlSystems.SisoRational{Float64}}\n", "10000.0s + 100000.0\n", "-------------------\n", " 10000.0s + 1.0\n", "\n", "Continuous-time transfer function model" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "α = 100000\n", "T1 = 0.1\n", "K1 = tf([α *T1, α ], [α *T1, 1])" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "setPlotScale(\"dB\")\n", "bodeplot(K1, lw=2, size=(450,400), legend=false, title=\"\" )" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ωₘ=0.03162277660168379\n", "ϕₘ=-89.63763088074153\n" ] } ], "source": [ "ωₘ = 1/T1/√α\n", "ϕₘ = asin( (1-α)/(1+α ) ) * 180/π\n", "println(\"ωₘ=\", ωₘ)\n", "println(\"ϕₘ=\", ϕₘ)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 位相進み" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "TransferFunction{Continuous, ControlSystems.SisoRational{Float64}}\n", "1.0s + 1.0\n", "----------\n", "0.1s + 1.0\n", "\n", "Continuous-time transfer function model" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "β = 0.1\n", "T2 = 1\n", "K2 = tf([T2, 1],[β*T2, 1])" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "setPlotScale(\"dB\")\n", "bodeplot(K2, lw=2, size=(450,400), legend=false, title=\"\" )" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ωₘ=3.162277660168379\n", "ϕₘ=54.9031987724154\n" ] } ], "source": [ "ωₘ = 1/T2/√β\n", "ϕₘ = asin( (1-β)/(1+β ) ) * 180/π\n", "println(\"ωₘ=\", ωₘ)\n", "println(\"ϕₘ=\", ϕₘ)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "TransferFunction{Continuous, ControlSystems.SisoRational{Float64}}\n", " 1.0s + 1.0\n", "-------------\n", "1.0e-6s + 1.0\n", "\n", "Continuous-time transfer function model" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "β = 0.000001\n", "T2 = 1\n", "K2 = tf([T2, 1],[β*T2, 1])" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "setPlotScale(\"dB\")\n", "w = exp10.( -2:0.01:3 )\n", "bodeplot(K2, w, lw=2, size=(450,400), legend=false, title=\"\" )" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ωₘ=1000.0\n", "ϕₘ=89.88540847917132\n" ] } ], "source": [ "ωₘ = 1/T2/√β\n", "ϕₘ = asin( (1-β)/(1+β ) ) * 180/π\n", "println(\"ωₘ=\", ωₘ)\n", "println(\"ϕₘ=\", ϕₘ)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## アームの角度制御(位相遅れ・進み補償)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "30" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g = 9.81 # 重力加速度[m/s^2]\n", "l = 0.2 # アームの長さ[m]\n", "M = 0.5 # アームの質量[kg]\n", "mu = 1.5e-2 # 粘性摩擦係数\n", "J = 1.0e-2 # 慣性モーメント\n", "\n", "P = tf( [0,1], [J, mu, M*g*l] )\n", "\n", "ref = 30 # 目標角度 [deg]" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "setPlotScale(\"dB\")\n", "w = exp10.( -2:0.001:3 )\n", "bodeplot(P, w, lw=2, size=(450,400), legend=false, title=\"\" )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "制御対象のボード線図.\n", "低周波ゲインが0[dB]なので,このままフィードバック系を構築しても定常偏差が残る." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 位相遅れ補償の設計" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "** 定常偏差を小さくするために,位相遅れ補償から設計する **\n", "\n", "低周波ゲインを上げるために,$\\alpha=20$とする.そして,ゲインを上げる周波数は,$T_1$で決めるが,最終的なゲイン交差周波数(ゲイン交差周波数の設計値)の10分の1程度を$1/T_1$にするために,$T_1=0.25$とする($1/T_1=40/10=4$)." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "TransferFunction{Continuous, ControlSystems.SisoRational{Float64}}\n", "5.0s + 20.0\n", "-----------\n", "5.0s + 1.0\n", "\n", "Continuous-time transfer function model\n" ] } ], "source": [ "α = 20\n", "T1 = 0.25\n", "K1 = tf([α*T1, α], [α*T1, 1])\n", "println(K1)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "H1 = P*K1\n", "setPlotScale(\"dB\")\n", "bodeplot(H1, lw=2, size=(450,400), legend=false, title=\"\" )" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-----------------------\n", "phase at 40rad/s =-183.1364012726378\n" ] } ], "source": [ "sys = freqresp(H1, [40])\n", "phaseH1at40 = atan(imag(sys)[],real(sys)[]) * (180/π)\n", "println(\"-----------------------\")\n", "println(\"phase at 40rad/s =\", phaseH1at40-360)\n", "#(注意)freqrespは -180 を下回っているときに +360 を加えて出力されるため phaseH1at40-360 を表示している\n", "# ただし,phaseH1at40 の値は,このあとの計算ではそのまま用いても問題ない" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "最終的にゲイン補償によって,ゲイン交差周波数を設計値の40[rad/s]まで上げるが,あげてしまうと,位相余裕が60[dB]を下回る.実際, 40[rad/s]における位相は -183[deg]程度なので,位相余裕は -3[deg]程度になってしまう.したがって,40[rad/s]での位相を -120[deg] まであげておく." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 位相進み補償の設計" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "** 位相進み補償の設計 ** \n", "\n", "40[rad/s]において位相を進ませる量は 60 - (180-183) = 63[deg]程度とする." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "TransferFunction{Continuous, ControlSystems.SisoRational{Float64}}\n", "0.10468126899830243s + 1.0\n", "---------------------------\n", "0.005970504618263038s + 1.0\n", "\n", "Continuous-time transfer function model\n" ] } ], "source": [ "ϕₘ= (60- (180 + phaseH1at40 ) ) * π/180\n", "β = (1-sin(ϕₘ))/(1+sin(ϕₘ))\n", "T2 = 1/40/√β\n", "K2 = tf([T2, 1],[β*T2, 1])\n", "println(K2)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "H2 = P*K1*K2\n", "setPlotScale(\"dB\")\n", "bodeplot(H2, lw=2, size=(450,400), legend=false, title=\"\" )" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-----------------------\n", "gain at 40rad/s =-11.058061395752679\n", "phase at 40rad/s =-119.99999999999997\n" ] } ], "source": [ "sys = freqresp(H2, [40])\n", "magH2at40 = abs(sys[])\n", "phaseH2at40 = atan(imag(sys)[],real(sys)[]) * (180/π)\n", "println(\"-----------------------\")\n", "println(\"gain at 40rad/s =\", 20*log10(magH2at40))\n", "println(\"phase at 40rad/s =\", phaseH2at40)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "位相進み補償により,40[rad/s]での位相が -120[deg]となっている.\n", "あとは,ゲイン補償により,40[rad/s]のゲインを 0[dB] にすればよい." ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.27996060941679224" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "magH2at40" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ゲイン補償の設計" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "** ゲイン補償の設計 **\n", "\n", "40[rad/s] におけるゲインが -11.06[dB] 程度なので, 11.06[dB]分上に移動させる.\n", "そのために,$k = 1/magL2at40$ をゲイン補償とする.\n", "これにより,40[rad/s]がゲイン交差周波数になり,位相余裕もPM=60[deg]となる." ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "k=3.571931073029088" ] } ], "source": [ "k = 1/magH2at40\n", "print(\"k=\", k)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "H = P*k*K1*K2\n", "setPlotScale(\"dB\")\n", "w = exp10.(-1:0.01:2)\n", "bodeplot([H, P], w, lw=2, size=(450,400),\n", " label=[\"After\" \"After\" \"Before\" \"Before\"] , title=\"\" )" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(wpc, GM, wgc, PM)\n", "([NaN;;], [Inf;;], [40.018325278977585;;], [60.00128104275365;;])\n" ] } ], "source": [ "println(\"(wpc, GM, wgc, PM)\")\n", "println(margin(H))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 閉ループ系の応答" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "error=0.013546052578222278\n", "------------------\n", "error=0.49520444220090865\n", "------------------\n" ] }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plt = plot()\n", "\n", "Gyr_H = feedback(H, 1)\n", "y, t = step( Gyr_H, 0:0.01:2 )\n", "plot!(plt, t, ref*y',\n", " xlabel=\"t\", #X軸のラベル\n", " ylabel=\"y\", #Y軸のラベル\n", " lw=2, #線幅\n", " ls=:solid, #線種\n", " label=\"H\",\n", " legend=:bottomright,\n", " size=(300,230) #プロットのサイズ \n", ")\n", "\n", "e_std = 1 - dcgain(Gyr_H)[]\n", "println(\"error=\", e_std) \n", "println(\"------------------\")\n", "\n", "Gyr_P = feedback(P, 1)\n", "y, t = step( Gyr_P, 0:0.01:2 )\n", "plot!(plt, t, ref*y',\n", " xlabel=\"t\", #X軸のラベル\n", " ylabel=\"y\", #Y軸のラベル\n", " lw=2, #線幅\n", " ls=:solid, #線種\n", " label=\"P\",\n", " legend=:bottomright,\n", " size=(300,230) #プロットのサイズ \n", ")\n", "\n", "e_std = 1 - dcgain(Gyr_P)[]\n", "println(\"error=\", e_std) \n", "println(\"------------------\")\n", "\n", "\n", "plot(plt)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Gyr = [ H/(1+H), P/(1+P)]\n", "\n", "setPlotScale(\"dB\")\n", "bodeplot(Gyr, lw=2, size=(450,400),\n", " label=[\"After\" \"After\" \"Before\" \"Before\"] , title=\"\" )" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "直流ゲイン =-0.11846369931437545\n", "------------------\n", "直流ゲイン =-5.937689510770942\n", "------------------\n" ] } ], "source": [ "println(\"直流ゲイン =\", 20*log10(dcgain(Gyr_H)[]) ) \n", "println(\"------------------\")\n", "println(\"直流ゲイン =\", 20*log10(dcgain(Gyr_P)[]) ) \n", "println(\"------------------\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Julia 1.7.0", "language": "julia", "name": "julia-1.7" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.7.0" } }, "nbformat": 4, "nbformat_minor": 4 }