diff --git a/Assignment 6 - Tuning PID/assign_6_pso.ipynb b/Assignment 6 - Tuning PID/assign_6_pso.ipynb
new file mode 100644
index 0000000..b0d2cf3
--- /dev/null
+++ b/Assignment 6 - Tuning PID/assign_6_pso.ipynb
@@ -0,0 +1,474 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "provenance": [],
+ "collapsed_sections": []
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "source": [
+ "
Tugas kelompok sisken
\n",
+ "\n",
+ "Anggota:\n",
+ "Nanda Riangga Damanik (19/442385/PA/19134)
\n",
+ "Gabriel Possenti (19/442374/PA/19123)
\n",
+ "Aziz
\n",
+ "Ivander Achmad W. (19/442377/PA/19126)
\n",
+ "\n",
+ "
"
+ ],
+ "metadata": {
+ "id": "NVGE7Ov689Yv"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "!pip install slycot\n",
+ "!pip install control"
+ ],
+ "metadata": {
+ "id": "rh1dEWqiX2eC",
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "outputId": "b54a86a3-fa44-408d-b9ca-ef57768a8b45"
+ },
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
+ "Collecting slycot\n",
+ " Downloading slycot-0.5.0.0.tar.gz (3.0 MB)\n",
+ "\u001b[K |████████████████████████████████| 3.0 MB 9.0 MB/s \n",
+ "\u001b[?25h Installing build dependencies ... \u001b[?25l\u001b[?25hdone\n",
+ " Getting requirements to build wheel ... \u001b[?25l\u001b[?25hdone\n",
+ " Preparing wheel metadata ... \u001b[?25l\u001b[?25hdone\n",
+ "Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from slycot) (1.21.6)\n",
+ "Building wheels for collected packages: slycot\n",
+ " Building wheel for slycot (PEP 517) ... \u001b[?25l\u001b[?25hdone\n",
+ " Created wheel for slycot: filename=slycot-0.5.0-cp37-cp37m-linux_x86_64.whl size=2021296 sha256=6b9d8a0f20baf1ad97ce3f430e682ef65ced6852f40883eea452ecae431e988f\n",
+ " Stored in directory: /root/.cache/pip/wheels/7f/2e/54/e2cb7cf358f956ed0efa9923ab4f5aa353a941422c55b25531\n",
+ "Successfully built slycot\n",
+ "Installing collected packages: slycot\n",
+ "Successfully installed slycot-0.5.0\n",
+ "Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n",
+ "Collecting control\n",
+ " Downloading control-0.9.2.tar.gz (398 kB)\n",
+ "\u001b[K |████████████████████████████████| 398 kB 7.0 MB/s \n",
+ "\u001b[?25hRequirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from control) (1.21.6)\n",
+ "Requirement already satisfied: scipy in /usr/local/lib/python3.7/dist-packages (from control) (1.7.3)\n",
+ "Requirement already satisfied: matplotlib in /usr/local/lib/python3.7/dist-packages (from control) (3.2.2)\n",
+ "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->control) (3.0.9)\n",
+ "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib->control) (0.11.0)\n",
+ "Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->control) (2.8.2)\n",
+ "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->control) (1.4.4)\n",
+ "Requirement already satisfied: typing-extensions in /usr/local/lib/python3.7/dist-packages (from kiwisolver>=1.0.1->matplotlib->control) (4.1.1)\n",
+ "Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.1->matplotlib->control) (1.15.0)\n",
+ "Building wheels for collected packages: control\n",
+ " Building wheel for control (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
+ " Created wheel for control: filename=control-0.9.2-py2.py3-none-any.whl size=403205 sha256=f381cd2cc15a36939fc5efc273768704c4457221132d0aac23a24b2d42574943\n",
+ " Stored in directory: /root/.cache/pip/wheels/48/ef/c2/929bb5c59a1328df00a0561d0e68cd7c8537f33f5ce0ce741b\n",
+ "Successfully built control\n",
+ "Installing collected packages: control\n",
+ "Successfully installed control-0.9.2\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "tlHXy4vZR402",
+ "outputId": "e79671b0-0c87-4431-8125-6dfbb452a639"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "5555.291048537736\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "%matplotlib inline\n",
+ "\n",
+ "import numpy as np\n",
+ "import seaborn as sns\n",
+ "import matplotlib.pyplot as plt\n",
+ "import control.matlab as control\n",
+ "\n",
+ "def step_info(t,yout):\n",
+ " print(\"% overshoot : \",(yout.max()/yout[-1]-1)*100,'%')\n",
+ " print(\"Rise time : \",t[next(i for i in range(0,len(yout)-1) if yout[i]>yout[-1]*.90)]-t[0])\n",
+ " print(\"%Settling time : \",t[next(len(yout)-i for i in range(2,len(yout)-1) if abs(yout[-i]/yout[-1])>1.02)]-t[0])\n",
+ "\n",
+ "s = control.tf('s')\n",
+ "J = 0.01\n",
+ "b = 0.1\n",
+ "K = 0.01\n",
+ "R = 1\n",
+ "L = 0.5\n",
+ "\n",
+ "num_motor = [K]\n",
+ "den_motor = [J*L, J*R+b*L, R*b+K*K]\n",
+ "\n",
+ "motor = control.tf(num_motor, den_motor)\n",
+ "\n",
+ "# Constant\n",
+ "c1=2\n",
+ "c2=2 \n",
+ "w_max = 1 \n",
+ "w_min = 0.1 \n",
+ "particles=50 \n",
+ "iterations=100\n",
+ "var=3 \n",
+ "e_max = 1 \n",
+ "e_min=0.1\n",
+ "\n",
+ "# Declaration\n",
+ "v = np.zeros([particles, var])\n",
+ "x = np.zeros([particles, var])\n",
+ "xp = np.zeros([particles, var])\n",
+ "xg = np.zeros([var])\n",
+ "ITAEp = np.zeros([particles])\n",
+ "ITAE = np.zeros([particles])\n",
+ "best_value = np.zeros([999999])\n",
+ "\n",
+ "\n",
+ "# Search limit\n",
+ "lim_min = 0\n",
+ "lim_max = 2500\n",
+ "\n",
+ "# limization steps\n",
+ "steps = 0\n",
+ "\n",
+ "# Initialization\n",
+ "for m in range(particles):\n",
+ " for n in range(var):\n",
+ " v[m,n]=0\n",
+ " x[m,n]=lim_min+np.random.rand()*(lim_max-lim_min)\n",
+ " xp[m,n]=x[m,n]\n",
+ "\n",
+ " # Model Parameters\n",
+ " Kp = x[m,0]\n",
+ " Ki = x[m,1]\n",
+ " Kd = x[m,2]\n",
+ " # Simulation Model\n",
+ " pid = control.tf([Kd,Kp,Ki],[0,1,0])\n",
+ " motor_cl = control.feedback(motor * pid, 1)\n",
+ " [y,t] = control.step(motor_cl)\n",
+ " # TIAE (Objective Function)\n",
+ " total = 0.0\n",
+ " T = len(y)\n",
+ " for t in range(T):\n",
+ " total = total + t*abs(y[t]-1)\n",
+ " ITAE[m] = total\n",
+ "\n",
+ "print(ITAE[0])\n",
+ "print(type(ITAE))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "prev_best = min(ITAE)\n",
+ "loc = np.searchsorted(ITAE, min(ITAE))\n",
+ "xg[0] = x[loc,0]\n",
+ "xg[1] = x[loc,1]\n",
+ "xg[2] = x[loc,2]"
+ ],
+ "metadata": {
+ "id": "xY1bhLrhz5tu"
+ },
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "for i in range(iterations):\n",
+ " e = e_max - ((e_max - e_min)*i)/iterations\n",
+ " w = w_min + ((iterations - i)*(w_max - w_min))/iterations\n",
+ " for m in range(particles):\n",
+ " for n in range(var):\n",
+ " v[m,n] = w*v[m,n] + c1*np.random.rand()*(xp[m,n]-x[m,n]) + c2*np.random.rand()*(xg[n]-x[m,n])\n",
+ " x[m,n] = x[m,n] + e*v[m,n];\n",
+ " # Constrain\n",
+ " if x[m,n] < lim_min:\n",
+ " x[m,n] = lim_min\n",
+ " if x[m,n] > lim_max:\n",
+ " x[m,n] = lim_max\n",
+ " \n",
+ " Kp = x[m,0]\n",
+ " Kp = x[m,1]\n",
+ " Kp = x[m,2]\n",
+ " pid = control.tf([Kd, Kp, Ki],[0,1,0])\n",
+ " motor_cl = control.feedback(motor * pid, 1)\n",
+ " [y,t] = control.step(motor_cl)\n",
+ "\n",
+ " total = 0\n",
+ " T = len(y)\n",
+ " for t in range(T):\n",
+ " total = total + (t*abs(y[t]-1))\n",
+ " \n",
+ " ITAEp[m] = total\n",
+ "\n",
+ " if ITAEp[m] < ITAE[m]:\n",
+ " ITAE[m] = ITAEp[m]\n",
+ " xp[m,0] = x[m,0]\n",
+ " xp[m,1] = x[m,1]\n",
+ " xp[m,2] = x[m,2]\n",
+ " \n",
+ "\n",
+ " now_best = min(ITAE)\n",
+ " loc = np.searchsorted(ITAE, min(ITAE))\n",
+ "\n",
+ " if now_best < prev_best:\n",
+ " prev_best = now_best\n",
+ " xg[0] = x[loc,0]\n",
+ " xg[1] = x[loc,1]\n",
+ " xg[2] = x[loc,2]\n",
+ " \n",
+ " steps = steps + 1\n",
+ " best_value[steps] = prev_best"
+ ],
+ "metadata": {
+ "id": "0fC4tNGBxRx9"
+ },
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "# Final testing\n",
+ "ITAE_min = prev_best\n",
+ "Kp = xg[0]\n",
+ "Ki = xg[1]\n",
+ "Kd = xg[2]\n",
+ "\n",
+ "pid = control.tf([Kd, Kp, Ki],[0,1,0])\n"
+ ],
+ "metadata": {
+ "id": "4EysKchgx--6"
+ },
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "motor_cl = control.feedback(motor * pid, 1)\n",
+ "motor_l = control.feedback(motor, 1)\n",
+ "\n"
+ ],
+ "metadata": {
+ "id": "WZ1DM3Y7i2m0"
+ },
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "(t,y) = control.step(motor_l)\n",
+ "\n",
+ "plt.plot(t,y)\n",
+ "plt.xlabel('motor_l')\n",
+ "plt.grid()"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 280
+ },
+ "id": "DTiYuZi00l7C",
+ "outputId": "301f6874-e439-4908-89c3-6e6a4b27b655"
+ },
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": [
+ "