Kalau seseorang bilang "kopinya panas", berapa derajat tepatnya? Tidak ada jawaban pasti — mungkin 60°C, 70°C, atau 80°C. Logika klasik (boolean) memaksa: panas = TRUE atau FALSE. Tapi kenyataannya bersifat gradual. Logika fuzzy mengatakan: "60°C itu sedikit panas (μ=0.3), 75°C itu cukup panas (μ=0.7), 90°C itu sangat panas (μ=1.0)". Itulah membership function!
Logika Klasik vs Logika Fuzzy
| Aspek | Logika Klasik (Crisp) | Logika Fuzzy |
|---|---|---|
| Nilai kebenaran | 0 atau 1 (binary) | 0.0 hingga 1.0 (kontinu) |
| Klasifikasi | "Dingin" atau "Panas" saja | "Sangat Dingin", "Dingin", "Sedang", "Panas", "Sangat Panas" |
| Transisi | Tiba-tiba (step function) | Bertahap (smooth membership function) |
| Pengetahuan | Matematis eksak | Linguistic rule dari pakar |
| Penerapan ke kontrol | PID, state-space | Fuzzy Controller |
Membership Function: Mengukur Derajat Keanggotaan
Suhu ruangan direpresentasikan dengan 5 himpunan fuzzy. Suhu 22°C bisa memiliki derajat keanggotaan di himpunan "Dingin" sebesar 0.4 DAN "Normal" sebesar 0.6 secara bersamaan — sesuatu yang tidak mungkin dalam logika klasik!
μ_PS(x) = max(0, 1 − |x − 5| / 5) ← segitiga, puncak di x=5
Nilai x=3: μ_ZE(3) = 0.4, μ_PS(3) = 0.6
x=3 adalah 40% "Nol" dan 60% "Positif Kecil" sekaligus!
Dokter tidak menghitung rumus ketika memeriksa pasien. Dia menggunakan aturan dari pengalaman: "JIKA demam TINGGI DAN tekanan darah RENDAH, MAKA resiko SANGAT TINGGI". Fuzzy Inference System bekerja persis sama — mengeksekusi aturan linguistik dari pakar secara matematis!
Fuzzifikasi
Nilai crisp → derajat keanggotaan μ
Rule Evaluation
Evaluasi semua IF-THEN rules
Aggregasi
Gabungkan output semua rules
Defuzzifikasi
Himpunan fuzzy → nilai crisp u(t)
Contoh Rule Base untuk Fuzzy PID (Error × ΔError → ΔKp)
| e \ Δe | NB | NS | ZE | PS | PB |
|---|---|---|---|---|---|
| NB | PB | PB | PM | PS | ZE |
| NS | PB | PM | PS | ZE | NS |
| ZE | PM | PS | ZE | NS | NM |
| PS | PS | ZE | NS | NM | NB |
| PB | ZE | NS | NM | NB | NB |
NB=Negatif Besar, NM=Negatif Medium, NS=Negatif Kecil, ZE=Nol, PS=Positif Kecil, PM=Positif Medium, PB=Positif Besar
Metode Defuzzifikasi
| Metode | Rumus | Kelebihan |
|---|---|---|
| Centroid (CoA) | u* = ∫μ(u)·u du / ∫μ(u) du | Paling populer, smooth output |
| Mean of Maximum | u* = rata-rata posisi puncak | Cepat secara komputasi |
| Weighted Average | u* = Σ(w_i · c_i) / Σw_i | Efisien untuk TSK fuzzy systems |
PID standar seperti pengemudi baru yang menginjak pedal gas dengan jumlah tetap per satuan kesalahan arah. Fuzzy PID seperti pengemudi berpengalaman: kalau masih jauh dari tujuan dan sedang melaju cepat → gas banyak; kalau sudah dekat tujuan → gas sedikit; kalau sudah persis di tujuan → pertahankan. Konteksnya dipahami!
Input: e(t), de/dt (atau Δe)
Output: u(t) langsung (fuzzy menggantikan PID)
Arsitektur 2 — Fuzzy sebagai tuner (lebih adaptif!):
Input: e(t), de/dt
Output: ΔKp, ΔKi, ΔKd (update parameter PID secara online)
Kp(t) = Kp_base + ΔKp_fuzzy(e, de/dt)
Ki(t) = Ki_base + ΔKi_fuzzy(e, de/dt)
🔑 Mengapa Fuzzy PID disebut "Adaptif"?
Dalam Arsitektur 2, Kp, Ki, Kd berubah secara online berdasarkan kondisi error saat ini. Ini adalah bentuk kontrol adaptif! Bedanya dengan MRAC/STR: tidak ada estimasi parameter sistem — Fuzzy langsung menggunakan aturan linguistik dari pakar untuk menyesuaikan gain. Tidak perlu model matematis!
Bayangkan sebuah tim: ahli kimia, ahli fisika, ahli komputer. Setiap ahli punya aturan berbeda untuk kondisi berbeda. Takagi-Sugeno Fuzzy System bekerja seperti ini: ada beberapa "lokal kontroller" (satu per operating region), dan fuzzy system memilih kombinasi bobotnya berdasarkan kondisi saat ini. Di kondisi transisi, beberapa ahli berkontribusi secara bersamaan!
Global model (weighted average):
ẋ = Σᵢ hᵢ(x) · [Aᵢx + Bᵢu]
hᵢ(x) = wᵢ(x) / Σⱼ wⱼ(x) (normalized firing strength)
wᵢ(x) = Πⱼ μ_{Aij}(xⱼ) (product t-norm)
💡 T-S Fuzzy + State Feedback = Kontrol Adaptif Nonlinier!
- Setiap rule memiliki kontroller linier lokal: uᵢ = −Kᵢx
- Output kontrol: u = Σᵢ hᵢ(x) · uᵢ = −[Σᵢ hᵢKᵢ] · x
- Gain efektif K(x) = Σhᵢ(x)Kᵢ berubah secara smooth sesuai kondisi → ini adalah gain scheduling yang otomatis dan nonlinier!
- Cocok untuk sistem sangat nonlinier: robot, turbin angin, reaktor kimia
Kasus 1: Manajemen Energi Smart Grid
Smart grid harus menyeimbangkan suplai (PLTS, PLTU, baterai) dengan permintaan yang terus berubah. Tidak ada model matematis eksak karena cuaca, sosial, dan ekonomi semua berpengaruh. Fuzzy Adaptive Control menggunakan aturan linguistik operator berpengalaman: "JIKA daya surya TURUN DAN beban NAIK MAKA aktifkan baterai SEGERA".
| Input Fuzzy | Variabel | Himpunan Fuzzy |
|---|---|---|
| Deviasi frekuensi | Δf (Hz) | NB, NS, ZE, PS, PB |
| State of Charge baterai | SoC (%) | Rendah, Sedang, Tinggi |
| Prediksi beban | ΔPL (MW) | Turun, Stabil, Naik |
| Output Fuzzy | Perintah baterai | Charge Cepat, Charge, Hold, Discharge, Discharge Cepat |
Kasus 2: Kontrol Traffic di Koridor Kritis
Traffic light konvensional: timer tetap. Traffic light fuzzy adaptif: durasi hijau disesuaikan berdasarkan kepadatan antrian dari sensor kamera. Aturan: "JIKA antrian SANGAT PANJANG dan waktu menunggu SANGAT LAMA MAKA tambah durasi hijau BANYAK".
import numpy as np import matplotlib.pyplot as plt # ========================================== # FUZZY PID: KONTROL FREKUENSI SMART GRID # Tanpa library eksternal — implementasi manual # ========================================== # === MEMBERSHIP FUNCTIONS === def trimf(x, a, b, c): """Triangular membership function""" return np.maximum(0, np.minimum((x-a)/(b-a+1e-10), (c-x)/(c-b+1e-10))) def fuzzify_error(e): """Fuzzifikasi error frekuensi (range -3 Hz to +3 Hz)""" nb = trimf(e, -3, -3, -1.5) # Negatif Besar ns = trimf(e, -3, -1.5, 0) # Negatif Kecil ze = trimf(e, -1.0, 0, 1.0) # Nol ps = trimf(e, 0, 1.5, 3) # Positif Kecil pb = trimf(e, 1.5, 3, 3) # Positif Besar return nb, ns, ze, ps, pb def fuzzy_kp_tuner(e, de): """Fuzzy tuner untuk Kp berdasarkan error dan perubahan error""" nb_e, ns_e, ze_e, ps_e, pb_e = fuzzify_error(e) nb_d, ns_d, ze_d, ps_d, pb_d = fuzzify_error(de*5) # scale de # Rule base (singleton output — Takagi-Sugeno) # Semakin besar error → Kp harus besar rules = { 'NB_NB': min(nb_e, nb_d) * 3.0, 'NB_ZE': min(nb_e, ze_d) * 2.5, 'NS_NS': min(ns_e, ns_d) * 2.0, 'ZE_ZE': min(ze_e, ze_d) * 1.0, # near setpoint → Kp kecil 'PS_PS': min(ps_e, ps_d) * 2.0, 'PB_ZE': min(pb_e, ze_d) * 2.5, 'PB_PB': min(pb_e, pb_d) * 3.0, } total_w = sum(rules.values()) + 1e-10 delta_Kp = sum(rules.values()) / total_w return np.clip(delta_Kp, 0.5, 3.5) def fuzzy_ki_tuner(e): """Ki kecil saat error besar (hindari windup), besar saat error kecil""" nb_e, ns_e, ze_e, ps_e, pb_e = fuzzify_error(e) ki = (nb_e + pb_e) * 0.1 + (ns_e + ps_e) * 0.3 + ze_e * 0.6 total = nb_e+pb_e+ns_e+ps_e+ze_e + 1e-10 return np.clip(ki/total, 0.05, 0.8) # === MODEL SISTEM: Load-Frequency Control === M=8; D=1.2; dt=0.05; T=80 t = np.arange(0, T, dt); N = len(t) P_load = np.zeros(N) P_load[int(5/dt):int(25/dt)] = 0.4 P_load[int(30/dt):int(50/dt)] = -0.3 P_load[int(55/dt):] = 0.6 # gangguan besar def simulate(use_fuzzy): f = np.zeros(N); integral_e = 0; prev_e = 0 Kp_hist = np.zeros(N); Ki_hist = np.zeros(N) for k in range(1, N): e = -f[k-1] de = (e - prev_e) / dt if use_fuzzy: Kp = fuzzy_kp_tuner(e, de) Ki = fuzzy_ki_tuner(e) else: Kp, Ki = 1.5, 0.3 # PID statis Kp_hist[k] = Kp; Ki_hist[k] = Ki integral_e = np.clip(integral_e + e*dt, -3, 3) P_gen = np.clip(Kp*e + Ki*integral_e, -1.5, 1.5) df = (P_gen - P_load[k] - D*f[k-1]) / M f[k] = f[k-1] + df*dt prev_e = e return f, Kp_hist, Ki_hist f_static, Kp_s, _ = simulate(use_fuzzy=False) f_fuzzy, Kp_f, Ki_f = simulate(use_fuzzy=True) # === PLOT === fig, axes = plt.subplots(3, 1, figsize=(12, 9)) axes[0].plot(t, f_static, 'tomato', lw=1.8, label='PID Statis (Kp=1.5, Ki=0.3)') axes[0].plot(t, f_fuzzy, 'lime', lw=2.0, label='Fuzzy PID (Kp,Ki adaptif)') axes[0].axhline(0, color='orange', ls='--', lw=1.5, label='Target Δf=0') axes[0].fill_between(t, -0.2, 0.2, alpha=0.07, color='lime') axes[0].set_ylabel('Δf (Hz)') axes[0].set_title('Smart Grid: Fuzzy PID vs PID Statis — Kontrol Frekuensi 50 Hz') axes[0].legend(fontsize=9); axes[0].grid(alpha=0.3) axes[1].plot(t, Kp_f, 'orange', lw=1.5, label='Kp Fuzzy (adaptif)') axes[1].axhline(1.5, color='tomato', ls='--', lw=1.2, alpha=0.7, label='Kp Statis=1.5') axes[1].set_ylabel('Nilai Kp') axes[1].set_title('Kp Fuzzy: Naik Otomatis saat Gangguan Besar, Turun saat Stabil') axes[1].legend(); axes[1].grid(alpha=0.3) axes[2].plot(t, P_load, 'red', lw=1.5, label='Gangguan Beban') axes[2].plot(t, Ki_f, 'cyan',lw=1.5, label='Ki Fuzzy') axes[2].set_xlabel('Waktu (s)'); axes[2].set_ylabel('Nilai') axes[2].set_title('Gangguan Beban vs Ki Fuzzy (Kecil saat Error Besar = Cegah Windup)') axes[2].legend(); axes[2].grid(alpha=0.3) plt.tight_layout(); plt.show() print(f"Max |Δf| PID Statis : {np.max(np.abs(f_static)):.4f} Hz") print(f"Max |Δf| Fuzzy PID : {np.max(np.abs(f_fuzzy)):.4f} Hz") print(f"RMSE PID Statis : {np.sqrt(np.mean(f_static**2)):.4f} Hz") print(f"RMSE Fuzzy PID : {np.sqrt(np.mean(f_fuzzy**2)):.4f} Hz") print(f"\n✅ Fuzzy PID tidak butuh model matematis sistem — hanya aturan linguistik!")
📊 Keunggulan Fuzzy PID vs PID Statis
- Saat gangguan besar (t=55), Kp fuzzy naik otomatis → deviasi frekuensi lebih kecil
- Ki fuzzy kecil saat error besar → mencegah integrator windup
- Ki fuzzy besar saat error kecil → mempercepat eliminasi steady-state error
- Tidak butuh model matematis sistem → bisa langsung dari pengetahuan operator PLN!
⚠️ Kekurangan Fuzzy Adaptive Control
- Tidak ada jaminan stabilitas formal seperti Lyapunov (kecuali dengan T-S fuzzy + LMI)
- Rule base bisa menjadi sangat besar untuk sistem MIMO kompleks
- Performanya sangat bergantung pada kualitas pengetahuan pakar dalam rule base
- Sulit di-tune secara sistematis — seringkali trial and error
🧠 Kuis Pemahaman Sesi 9
1. Perbedaan utama logika fuzzy vs logika klasik (crisp) adalah?
2. Dalam Fuzzy Inference System, proses "defuzzifikasi" berfungsi untuk?
3. Mengapa Fuzzy Adaptive Control disebut "tidak memerlukan model matematis eksak"?