- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 1. 신호와 시스템 기초
- 2. 푸리에 급수 (Fourier Series)
- 3. 푸리에 변환 (Fourier Transform)
- 4. 이산 푸리에 변환 (DFT) & FFT
- 5. 라플라스 변환 (Laplace Transform)
- 6. Z-변환
- 7. 디지털 필터 설계
- 8. 제어시스템 기초
- 9. PID 제어기
- 10. 상태 공간 표현 (State Space)
- 11. AI/ML과 신호처리
- 12. 퀴즈
- 참고 문헌
1. 신호와 시스템 기초
1.1 신호의 분류
신호(Signal)는 정보를 전달하는 물리적 양의 변화입니다. 기본 분류는 다음과 같습니다.
연속시간 신호 vs 이산시간 신호
연속시간 신호(CT Signal)는 모든 시간 에서 정의됩니다. 예: 아날로그 음성 신호
이산시간 신호(DT Signal)는 정수 인덱스 에서만 정의됩니다. 예: 디지털 오디오 샘플
에너지 신호와 전력 신호
신호의 에너지 와 평균 전력 :
이면 에너지 신호, 이면 전력 신호입니다.
1.2 기본 신호
단위 임펄스(Unit Impulse)
체(Sifting) 성질:
단위 계단(Unit Step)
관계가 성립합니다.
1.3 선형 시불변(LTI) 시스템
LTI 시스템은 두 가지 핵심 성질을 만족합니다.
- 선형성(Linearity):
- 시불변성(Time Invariance):
1.4 컨볼루션
LTI 시스템의 출력은 입력과 임펄스 응답의 컨볼루션으로 표현됩니다.
이산시간의 경우:
컨볼루션은 교환법칙, 결합법칙, 분배법칙을 만족합니다.
2. 푸리에 급수 (Fourier Series)
2.1 주기 신호의 푸리에 급수
주기 를 갖는 신호 는 복소 지수 함수의 합으로 표현됩니다. 기본 주파수는 입니다.
푸리에 계수:
2.2 구형파(Square Wave) 예제
진폭 A, 주기 T, 듀티 사이클 50%인 구형파의 푸리에 계수:
홀수 고조파만 존재하며, 고차 고조파일수록 진폭이 감소합니다. 기브스 현상(Gibbs Phenomenon)이 불연속점 근방에서 나타납니다.
2.3 파셀발 정리
시간 영역의 평균 전력과 주파수 영역의 계수 제곱합이 같습니다.
3. 푸리에 변환 (Fourier Transform)
3.1 연속 푸리에 변환 (CTFT)
비주기 신호에 대한 푸리에 변환 쌍:
3.2 중요 변환 쌍
| 신호 | 푸리에 변환 |
|---|---|
| 구형파 |
3.3 푸리에 변환 성질
- 선형성:
- 시간 이동:
- 주파수 이동(변조):
- 컨볼루션 정리:
- 곱셈 정리:
- 미분:
- 파셀발:
3.4 Python으로 푸리에 변환 계산
import numpy as np
from scipy.fft import fft, ifft, fftfreq, fftshift
import matplotlib.pyplot as plt
# 구형파 신호 생성
fs = 1000 # 샘플링 주파수 (Hz)
T = 1.0 # 신호 길이 (초)
t = np.linspace(0, T, int(fs * T), endpoint=False)
# 구형파: 주기 0.1초 (10Hz)
from scipy.signal import square
x = square(2 * np.pi * 10 * t)
# FFT 계산
N = len(x)
X = fft(x)
freqs = fftfreq(N, 1/fs)
# 양측 스펙트럼 (정규화)
magnitude = np.abs(fftshift(X)) / N
freq_shifted = fftshift(freqs)
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(t[:100], x[:100])
plt.title('Square Wave (time domain)')
plt.xlabel('Time (s)')
plt.subplot(1, 2, 2)
plt.plot(freq_shifted, magnitude)
plt.xlim(-100, 100)
plt.title('Fourier Transform (frequency domain)')
plt.xlabel('Frequency (Hz)')
plt.tight_layout()
plt.show()
4. 이산 푸리에 변환 (DFT) & FFT
4.1 이산 시간 푸리에 변환 (DTFT)
이산 시간 신호 의 DTFT:
역변환:
DTFT는 주파수 가 연속적이며 주기를 갖습니다.
4.2 DFT 정의
점 DFT는 DTFT를 개 주파수에서 균등 샘플링한 것입니다.
역 DFT:
4.3 FFT 알고리즘
직접 DFT 계산 복잡도는 이지만, FFT(Cooley-Tukey 알고리즘)는 입니다. 일 때 분할 정복(Divide and Conquer)으로 구현합니다.
회전 인수(Twiddle Factor):
4.4 스펙트럼 분석 예제
import numpy as np
from scipy.fft import fft, fftfreq
import matplotlib.pyplot as plt
# 신호 생성: 50Hz + 120Hz 복합 신호
fs = 1000 # 샘플링 주파수 (Hz)
N = fs # 샘플 수 (1초)
t = np.linspace(0, 1, N, endpoint=False)
# 복합 신호 (노이즈 포함)
signal = (np.sin(2 * np.pi * 50 * t)
+ 0.5 * np.sin(2 * np.pi * 120 * t)
+ 0.2 * np.random.randn(N))
# FFT 계산
yf = fft(signal)
xf = fftfreq(N, 1/fs)
# 단측 스펙트럼 (양수 주파수만)
half = N // 2
amplitude = 2.0 / N * np.abs(yf[:half])
freq_pos = xf[:half]
plt.figure(figsize=(10, 4))
plt.plot(freq_pos, amplitude)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Amplitude')
plt.title('Single-Sided Amplitude Spectrum')
plt.axvline(x=50, color='r', linestyle='--', label='50 Hz')
plt.axvline(x=120, color='g', linestyle='--', label='120 Hz')
plt.legend()
plt.grid(True)
plt.show()
# 주파수 해상도: delta_f = fs / N = 1 Hz
print(f"Frequency resolution: {fs/N} Hz")
print(f"Nyquist frequency: {fs/2} Hz")
4.5 샘플링 정리 (Nyquist-Shannon)
샘플링 주파수 가 신호의 최대 주파수 의 두 배 이상이어야 에일리어싱(Aliasing) 없이 복원 가능합니다.
5. 라플라스 변환 (Laplace Transform)
5.1 정의
양측(Bilateral) 라플라스 변환:
단측(Unilateral) 라플라스 변환:
5.2 중요 변환 쌍
| 신호 | 변환 | 수렴 영역 |
|---|---|---|
| 전체 s-평면 | ||
5.3 전달 함수 (Transfer Function)
LTI 시스템의 입출력 관계를 s-영역에서 표현:
극점(Poles): 가 되는 값 (분모 = 0)
영점(Zeros): 이 되는 값 (분자 = 0)
극점의 위치가 시스템 안정성을 결정합니다. 모든 극점이 좌반 s-평면(LHP)에 있으면 BIBO 안정합니다.
5.4 2차 시스템 표준형
- : 자연 주파수(Natural Frequency)
- : 감쇠비(Damping Ratio)
- : 부족 감쇠(Underdamped) — 진동 응답
- : 임계 감쇠(Critically Damped) — 가장 빠른 무진동
- : 과감쇠(Overdamped) — 느린 무진동
6. Z-변환
6.1 정의
이산시간 신호 의 Z-변환:
(단위 원 위)로 치환하면 DTFT와 동일합니다.
6.2 Z-변환과 라플라스 변환의 관계
연속시간 시스템을 샘플링 주기 로 이산화할 때:
이 관계로 s-평면과 z-평면이 대응됩니다.
- s-평면의 허수축 z-평면의 단위 원
- s-평면의 좌반면 z-평면의 단위 원 내부
6.3 안정성 분석
이산시간 시스템이 안정하려면 모든 극점이 단위 원 내부에 있어야 합니다.
6.4 중요 Z-변환 쌍
| 신호 | Z-변환 |
|---|---|
7. 디지털 필터 설계
7.1 FIR vs IIR 필터
FIR (Finite Impulse Response) 필터
- 임펄스 응답이 유한 길이
- 항상 안정 (피드백 없음)
- 선형 위상 구현 가능
- 급격한 차단 특성을 위해 높은 차수 필요
IIR (Infinite Impulse Response) 필터
- 피드백 포함, 임펄스 응답 무한
- 낮은 차수로 급격한 차단 특성
- 위상 비선형 (위상 왜곡 발생 가능)
- 설계 불량 시 불안정
7.2 필터 유형
- 저역통과 (LPF): 낮은 주파수 통과, 높은 주파수 차단
- 고역통과 (HPF): 높은 주파수 통과, 낮은 주파수 차단
- 대역통과 (BPF): 특정 주파수 대역만 통과
- 대역저지 (BEF/Notch): 특정 주파수 대역 차단
7.3 필터 설계 함수
버터워스(Butterworth): 통과대역에서 최대한 평탄한 응답
체비셰프(Chebyshev) I형: 통과대역에 리플 허용, 더 급격한 차단
타원(Elliptic): 통과대역과 저지대역 모두 리플, 최소 차수로 최대 감쇠
7.4 scipy.signal을 이용한 필터 설계
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
# 샘플링 주파수
fs = 1000 # Hz
# 버터워스 저역통과 필터 (4차, 차단 주파수 100Hz)
nyq = fs / 2
cutoff = 100 / nyq # 정규화된 주파수 (0~1)
b_butter, a_butter = signal.butter(N=4, Wn=cutoff, btype='low')
# 체비셰프 I형 (4차, 1dB 리플, 차단 주파수 100Hz)
b_cheby, a_cheby = signal.cheby1(N=4, rp=1, Wn=cutoff, btype='low')
# 주파수 응답 계산
w, h_butter = signal.freqz(b_butter, a_butter, fs=fs)
w, h_cheby = signal.freqz(b_cheby, a_cheby, fs=fs)
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.plot(w, 20 * np.log10(np.abs(h_butter)), label='Butterworth')
plt.plot(w, 20 * np.log10(np.abs(h_cheby)), label='Chebyshev I')
plt.xlabel('Frequency (Hz)')
plt.ylabel('Magnitude (dB)')
plt.title('Filter Frequency Response')
plt.legend()
plt.grid(True)
plt.ylim(-80, 5)
# 노이즈가 낀 신호 필터링
t = np.linspace(0, 1, fs, endpoint=False)
clean = np.sin(2 * np.pi * 50 * t)
noisy = clean + 0.5 * np.sin(2 * np.pi * 300 * t)
filtered = signal.filtfilt(b_butter, a_butter, noisy)
plt.subplot(1, 2, 2)
plt.plot(t[:200], noisy[:200], alpha=0.5, label='Noisy')
plt.plot(t[:200], filtered[:200], label='Filtered')
plt.xlabel('Time (s)')
plt.legend()
plt.title('Filtering Result')
plt.tight_layout()
plt.show()
7.5 FIR 필터 설계 (Window Method)
from scipy.signal import firwin, freqz
# Hamming 윈도우를 사용한 FIR LPF
# 탭 수 = 51, 차단 주파수 = 100Hz
numtaps = 51
cutoff_hz = 100
b_fir = firwin(numtaps, cutoff_hz / (fs/2), window='hamming')
# 주파수 응답
w_fir, h_fir = freqz(b_fir, [1.0], fs=fs)
print(f"FIR filter order: {numtaps - 1}")
print(f"Linear phase: True (symmetric coefficients)")
8. 제어시스템 기초
8.1 개루프 vs 폐루프 제어
개루프(Open-Loop) 제어: 출력이 제어 동작에 영향을 주지 않습니다. 단순하지만 외란이나 모델 오차에 취약합니다.
폐루프(Closed-Loop) 제어: 출력을 측정하여 기준 입력과 비교하고 오차를 최소화합니다. 피드백(Feedback)으로 강인성이 높습니다.
기본 피드백 루프:
여기서 는 플랜트(Plant), 는 센서 전달 함수입니다.
8.2 안정성: 루스-허비츠 기준
특성 방정식 의 근이 모두 좌반 s-평면에 있으면 안정합니다.
루스 배열(Routh Array)을 이용하여 계수만으로 극점 위치를 판별합니다. 첫 열의 부호 변화 횟수가 우반면 극점 수와 같습니다.
8.3 보데 선도 (Bode Plot)
주파수 응답 를 로그 스케일로 표현합니다.
- 이득 선도: [dB] vs
- 위상 선도: [도] vs
안정도 여유:
- 위상 여유(Phase Margin, PM): 이득이 0 dB일 때 위상이 -180도에서 얼마나 여유가 있는지
- 이득 여유(Gain Margin, GM): 위상이 -180도일 때 이득이 0 dB에서 얼마나 여유가 있는지
PM > 45도, GM > 6 dB이면 일반적으로 안정한 시스템으로 봅니다.
from scipy import signal
import matplotlib.pyplot as plt
import numpy as np
# 2차 시스템 전달 함수: H(s) = 10 / (s^2 + 2s + 10)
num = [10]
den = [1, 2, 10]
sys = signal.TransferFunction(num, den)
# 보데 선도
w, mag, phase = signal.bode(sys)
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 6))
ax1.semilogx(w, mag)
ax1.set_ylabel('Magnitude (dB)')
ax1.set_title('Bode Plot')
ax1.grid(True, which='both')
ax2.semilogx(w, phase)
ax2.set_ylabel('Phase (degrees)')
ax2.set_xlabel('Frequency (rad/s)')
ax2.grid(True, which='both')
plt.tight_layout()
plt.show()
9. PID 제어기
9.1 PID 제어 동작
PID 제어기는 세 가지 동작의 합입니다.
여기서 는 오차 신호입니다.
- 비례(P) 제어: 현재 오차에 비례한 제어 출력. 빠른 응답이지만 정상상태 오차 잔존.
- 적분(I) 제어: 누적 오차를 제거하여 정상상태 오차를 0으로. 응답 느려짐.
- 미분(D) 제어: 오차 변화율에 반응하여 오버슈트 억제. 노이즈에 민감.
전달 함수:
9.2 지글러-니콜스 튜닝
방법 1 (개루프 스텝 응답):
공정 응답 곡선에서 지연 시간 과 시정수 를 구한 후:
| 제어기 | |||
|---|---|---|---|
| P | - | - | |
| PI | - | ||
| PID |
방법 2 (폐루프 한계 감도):
으로 놓고 를 증가시켜 지속 진동이 일어나는 임계 이득 와 진동 주기 를 구합니다.
| 제어기 | |||
|---|---|---|---|
| PID |
9.3 Python으로 PID 시뮬레이션
import numpy as np
import matplotlib.pyplot as plt
class PIDController:
def __init__(self, kp, ki, kd, dt):
self.kp = kp
self.ki = ki
self.kd = kd
self.dt = dt
self.integral = 0.0
self.prev_error = 0.0
def update(self, setpoint, measured):
error = setpoint - measured
self.integral += error * self.dt
derivative = (error - self.prev_error) / self.dt
output = self.kp * error + self.ki * self.integral + self.kd * derivative
self.prev_error = error
return output
# 1차 플랜트: dy/dt = -y + u (시정수 1초)
def plant_step(y, u, dt):
return y + dt * (-y + u)
# 시뮬레이션 파라미터
dt = 0.01
t = np.arange(0, 10, dt)
setpoint = 1.0
# PID 게인 설정 (지글러-니콜스 기반 튜닝)
pid = PIDController(kp=2.0, ki=1.0, kd=0.5, dt=dt)
y = 0.0
y_list = []
for _ in t:
u = pid.update(setpoint, y)
u = np.clip(u, -10, 10) # 액추에이터 포화 제한
y = plant_step(y, u, dt)
y_list.append(y)
plt.figure(figsize=(10, 4))
plt.plot(t, y_list, label='Plant Output')
plt.axhline(setpoint, color='r', linestyle='--', label='Setpoint')
plt.xlabel('Time (s)')
plt.ylabel('Output')
plt.title('PID Control Simulation')
plt.legend()
plt.grid(True)
plt.show()
10. 상태 공간 표현 (State Space)
10.1 상태 방정식
연속시간 LTI 시스템의 상태 공간 표현:
- : 상태 벡터 ()
- : 입력 벡터 ()
- : 출력 벡터 ()
- : 시스템 행렬 ()
- : 입력 행렬 ()
- : 출력 행렬 ()
- : 직결 행렬 ()
전달 함수와의 관계:
10.2 가관측성과 가제어성
가제어성(Controllability): 임의의 초기 상태에서 유한 시간 내에 원하는 상태로 이동 가능한가?
가제어성 행렬 의 계수가 이면 완전 가제어.
가관측성(Observability): 출력만으로 초기 상태를 결정 가능한가?
가관측성 행렬 의 계수가 이면 완전 가관측.
10.3 선형 이차 조절기 (LQR)
비용 함수를 최소화하는 최적 상태 피드백 제어:
최적 제어 입력:
는 상태 오차 가중치, 은 제어 입력 에너지 가중치입니다.
import numpy as np
from scipy import linalg
# 이중 적분기 시스템 예제
# x'' = u (2차 시스템)
A = np.array([[0, 1], [0, 0]])
B = np.array([[0], [1]])
C = np.array([[1, 0]])
D = np.array([[0]])
# LQR 가중치
Q = np.diag([10, 1]) # 위치 오차를 더 중요시
R = np.array([[1]])
# 리카티 방정식 풀기
P = linalg.solve_continuous_are(A, B, Q, R)
K = np.linalg.inv(R) @ B.T @ P
print("LQR Gain K:", K)
print("Closed-loop poles:", np.linalg.eigvals(A - B @ K))
11. AI/ML과 신호처리
11.1 CNN for 1D Signal
1D 합성곱 신경망은 ECG, 지진 신호, 음성 등 시간 시리즈 신호의 패턴 인식에 뛰어납니다.
import torch
import torch.nn as nn
class Signal1DCNN(nn.Module):
def __init__(self, num_classes=5):
super().__init__()
self.conv_layers = nn.Sequential(
nn.Conv1d(1, 32, kernel_size=7, padding=3),
nn.BatchNorm1d(32),
nn.ReLU(),
nn.MaxPool1d(2),
nn.Conv1d(32, 64, kernel_size=5, padding=2),
nn.BatchNorm1d(64),
nn.ReLU(),
nn.MaxPool1d(2),
nn.Conv1d(64, 128, kernel_size=3, padding=1),
nn.ReLU(),
nn.AdaptiveAvgPool1d(8)
)
self.classifier = nn.Sequential(
nn.Flatten(),
nn.Linear(128 * 8, 256),
nn.ReLU(),
nn.Dropout(0.5),
nn.Linear(256, num_classes)
)
def forward(self, x):
x = self.conv_layers(x)
return self.classifier(x)
# 사용 예시
model = Signal1DCNN(num_classes=5)
# 입력 형태: (batch_size, channels=1, sequence_length=1000)
x = torch.randn(8, 1, 1000)
output = model(x)
print("Output shape:", output.shape) # (8, 5)
11.2 STFT와 Mel-Spectrogram
음성 AI에서는 신호를 시간-주파수 표현으로 변환한 후 CNN으로 처리하는 방법이 널리 사용됩니다.
import librosa
import librosa.display
import matplotlib.pyplot as plt
import numpy as np
# 오디오 로드
# y, sr = librosa.load('audio.wav', sr=22050)
# STFT (Short-Time Fourier Transform)
# D = librosa.stft(y)
# S_db = librosa.amplitude_to_db(np.abs(D), ref=np.max)
# Mel-Spectrogram
# mel_spec = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128)
# mel_db = librosa.power_to_db(mel_spec, ref=np.max)
# MFCC (Mel-Frequency Cepstral Coefficients)
# mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13)
print("STFT window: Hann window, hop_length=512, n_fft=2048")
print("Mel-filterbank: 128 mel bands, 0Hz ~ Nyquist")
print("MFCC: 13 coefficients commonly used for speech recognition")
11.3 신호처리 + 딥러닝 응용 사례
- ECG 부정맥 분류: 1D CNN + LSTM으로 심장 리듬 이상 감지
- 이상 진동 감지: FFT 특징 추출 후 오토인코더로 이상 탐지
- 음성 인식: MFCC + Transformer (Whisper, wav2vec 2.0)
- 지진 감지: 지진계 신호의 P파/S파 자동 분류
- 뇌파(EEG) 분석: 주파수 대역별 파워 스펙트럼으로 집중도/수면 상태 분류
12. 퀴즈
Q1. 샘플링 주파수가 8000 Hz인 시스템에서 에일리어싱 없이 표현할 수 있는 최대 신호 주파수는?
정답: 4000 Hz
해설: 나이퀴스트-섀넌 샘플링 정리에 의해 샘플링 주파수의 절반인 나이퀴스트 주파수(4000 Hz)가 에일리어싱 없이 표현 가능한 최대 주파수입니다. 전화 음성 코덱(8 kHz 샘플링)이 최대 4 kHz 음성을 처리하는 이유가 이것입니다.
Q2. FIR 필터가 IIR 필터에 비해 갖는 가장 큰 장점은 무엇인가?
정답: 선형 위상 특성과 무조건적 안정성
해설: FIR 필터는 피드백이 없으므로 항상 BIBO 안정합니다. 또한 계수를 대칭으로 설계하면 선형 위상(linear phase)을 보장하여 모든 주파수 성분의 지연이 동일합니다. 이는 위상 왜곡이 허용되지 않는 데이터 통신 등에서 중요합니다. 반면 IIR 필터는 낮은 차수로 급격한 차단 특성을 얻을 수 있다는 장점이 있습니다.
Q3. PID 제어기에서 미분(D) 동작의 역할과 단점은?
정답: 오차의 변화율에 반응하여 오버슈트를 억제하지만, 측정 노이즈에 매우 민감합니다.
해설: D 동작은 오차가 빠르게 변화할 때 강한 제어 출력을 생성하여 시스템이 목표값을 지나치는 현상(오버슈트)을 억제합니다. 그러나 노이즈가 있는 측정값을 미분하면 노이즈가 증폭됩니다. 실용적 PID에서는 미분 필터(low-pass filter on derivative term)를 추가하거나, 출력을 직접 미분하는 Derivative on Measurement 방식을 사용합니다.
Q4. Z-변환에서 디지털 필터의 안정성 조건은?
정답: 모든 극점(poles)이 z-평면의 단위 원 내부에 위치해야 합니다.
해설: 이산시간 시스템의 극점 위치와 안정성의 관계: 단위 원 내부(절댓값 1 미만)이면 안정, 단위 원 위이면 임계 안정, 단위 원 외부이면 불안정합니다. 이는 연속시간에서 극점이 s-평면의 좌반면에 있어야 안정한 것과 대응됩니다. z = exp(sT) 변환에서 좌반면이 단위 원 내부로 매핑됩니다.
Q5. 보데 선도에서 위상 여유(Phase Margin)가 음수라면 시스템은?
정답: 불안정(Unstable)합니다.
해설: 위상 여유는 이득 교차 주파수(gain crossover frequency, 이득이 0 dB인 주파수)에서의 위상이 -180도에서 얼마나 떨어져 있는지를 나타냅니다. 위상 여유가 음수이면 이득이 0 dB일 때 위상이 이미 -180도를 지나쳤다는 의미로, 폐루프 시스템이 불안정합니다. 일반적으로 안정하고 좋은 응답 특성을 위해 PM은 45도 ~ 60도를 목표로 설계합니다.
참고 문헌
- Oppenheim, A. V. & Schafer, R. W. — Discrete-Time Signal Processing (3rd ed.), Prentice Hall, 2010
- Ogata, K. — Modern Control Engineering (5th ed.), Prentice Hall, 2010
- Proakis, J. G. & Manolakis, D. G. — Digital Signal Processing, Prentice Hall, 2007
- SciPy Signal Processing Documentation — https://docs.scipy.org/doc/scipy/reference/signal.html
- MIT OpenCourseWare 6.003 — Signals and Systems — https://ocw.mit.edu/courses/6-003-signals-and-systems-fall-2011/
- NumPy FFT 문서 — https://numpy.org/doc/stable/reference/routines.fft.html