Poprawki do testera - konwersja jednostek i obsługa przekładni
- Poprawiono obliczanie impedancji dla danych pierwotnych - Dodano parametry PRZEKLADNIA i PRZEKLADNIA_NAPIECIA - Dane są teraz konwertowane do wartości wtórnych przed obliczeniami - Test na danych MOR-MIL: zwarcie wykryte prawidłowo Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
57
tester.py
57
tester.py
@@ -30,6 +30,23 @@ else:
|
||||
print(f"=== Używany algorytm: {ALGORITHM_DESC} ===")
|
||||
# ============================================================
|
||||
|
||||
# Przekładnia prądowa (domyślna) - zmień tę wartość dla swoich danych
|
||||
# Dla rejestracji MOR-MIL: przekładnia 1000/5 = 200
|
||||
# Dane z rejestracji są w wartościach PIERWOTNYCH
|
||||
# Algorytm oczekuje wartości WTÓRNYCH
|
||||
# Konwersja: dane_wtórne = dane_pierwotne / PRZEKLADNIA
|
||||
PRZEKLADNIA = 200.0 # <-- zmień tę wartość (np. 200 dla przekładni 1000/5)
|
||||
PRZEKLADNIA_NAPIECIA = 1100.0 # 110kV/100V = 1100
|
||||
# Przekładnia efektywna dla Z = U/I
|
||||
# Z_wt = (U_pierw/n_U) / (I_pierw/n_I) = Z_pierw * n_I/n_U
|
||||
# Z_wt = Z_pierw / (PRZEKLADNIA_NAPIECIA / PRZEKLADNIA)
|
||||
PRZEKLADNIA_EFF = PRZEKLADNIA_NAPIECIA / PRZEKLADNIA # = 1100/200 = 5.5
|
||||
|
||||
# Kierunek zabezpieczenia:
|
||||
|
||||
# Kierunek zabezpieczenia: 0=bez, 1=do linii, 2=do szyn
|
||||
KIERUNEK = 0 # <-- zmień tę wartość (0=bez, 1=do linii, 2=do szyn)
|
||||
|
||||
# Obsluga argumentow wiersza polecen
|
||||
if len(sys.argv) > 1:
|
||||
base_name = sys.argv[1] # Nazwa pliku bez rozszerzenia
|
||||
@@ -44,7 +61,7 @@ print(f"Wczytywanie rejestracji: {cfg_file}")
|
||||
rec = Comtrade()
|
||||
|
||||
# Probuj rozne kodowania dla plikow CFG
|
||||
encodings = ['utf-8', 'cp1250', 'cp1252', 'latin-1', 'iso-8859-1']
|
||||
encodings = ['utf-8', 'cp1250', 'cp1252', 'latin-1', 'iso-8859-1', 'cp1251', 'cp1253']
|
||||
loaded = False
|
||||
|
||||
for encoding in encodings:
|
||||
@@ -83,13 +100,25 @@ print(f" Liczba probek na okres: {N}")
|
||||
max_analog = min(6, num_analog)
|
||||
|
||||
# Pobierz tyle ile mamy
|
||||
# Indeksy dla standardowych rejestracji (6 kanałów):
|
||||
# 0:I_L1, 1:I_L2, 2:I_L3, 3:U_L1, 4:U_L2, 5:U_L3
|
||||
# Dla MOR-MIL (22 kanały):
|
||||
# 0:I_L1, 1:I_L2, 2:I_L3, 3:3Io, 4:U_L1, 5:U_L2, 6:U_L3
|
||||
i1_raw = np.array(rec.analog[0])
|
||||
i2_raw = np.array(rec.analog[1]) # Kanał 1: I_L2
|
||||
i3_raw = np.array(rec.analog[2]) # Kanał 2: I_L3
|
||||
u1_raw = np.array(rec.analog[3]) # Kanał 3: U_L1
|
||||
u2_raw = np.array(rec.analog[4]) # Kanał 4: U_L2
|
||||
u3_raw = np.array(rec.analog[5]) # Kanał 5: U_L3
|
||||
# (musisz dopasować indeksy analog[] do swojego pliku .cfg)
|
||||
i2_raw = np.array(rec.analog[1])
|
||||
i3_raw = np.array(rec.analog[2])
|
||||
|
||||
# Wykryj typ rejestracji na podstawie liczby kanałów
|
||||
if num_analog >= 7:
|
||||
# Rejestracja z 7+ kanałami - użyj indeksów dla U_L1, U_L2, U_L3
|
||||
u1_raw = np.array(rec.analog[4])
|
||||
u2_raw = np.array(rec.analog[5])
|
||||
u3_raw = np.array(rec.analog[6])
|
||||
else:
|
||||
# Standardowa rejestracja 6 kanałowa
|
||||
u1_raw = np.array(rec.analog[3])
|
||||
u2_raw = np.array(rec.analog[4])
|
||||
u3_raw = np.array(rec.analog[5])
|
||||
|
||||
# === ANALIZA DANYCH - wyznaczenie impedancji przed zwarciem ===
|
||||
print(f" Czestotliwosc probkowania: {Fs} Hz")
|
||||
@@ -121,6 +150,12 @@ def calculate_impedance_from_raw(u_raw, i_raw, idx):
|
||||
i_mag_sq = i_re**2 + i_im**2
|
||||
if i_mag_sq < 1e-9:
|
||||
return 0, 0
|
||||
# Z_wt = Z_pierw / (n_U / n_I) = Z_pierw / PRZEKLADNIA_EFF
|
||||
i_re = i_re / PRZEKLADNIA
|
||||
i_im = i_im / PRZEKLADNIA
|
||||
u_re = u_re / PRZEKLADNIA_NAPIECIA
|
||||
u_im = u_im / PRZEKLADNIA_NAPIECIA
|
||||
i_mag_sq = i_re**2 + i_im**2
|
||||
z_re = (u_re * i_re + u_im * i_im) / i_mag_sq
|
||||
z_x = (u_im * i_re - u_re * i_im) / i_mag_sq
|
||||
return z_re, z_x
|
||||
@@ -161,7 +196,7 @@ else:
|
||||
print("Nie mozna wyznaczyc impedancji linii, uzywam wartosci domyslnych")
|
||||
|
||||
# Utworzenie relay z automatycznie dobranymi nastawami
|
||||
relay = DistanceRelay(Z_line_R=Z_line_R, Z_line_X=Z_line_X, line_angle=line_angle)
|
||||
relay = DistanceRelay(Z_line_R=Z_line_R, Z_line_X=Z_line_X, line_angle=line_angle, kierunek=KIERUNEK)
|
||||
|
||||
# Macierz operatora obrotu dla składowych symetrycznych
|
||||
a = complex(-0.5, np.sqrt(3)/2)
|
||||
@@ -185,6 +220,10 @@ z3_x_history = []
|
||||
|
||||
def calculate_impedance(u_cpx, i_cpx):
|
||||
"""Oblicza impedancję Z = U/I jako liczbę zespoloną"""
|
||||
# Konwersja do wartości wtórnych
|
||||
i_cpx = complex(i_cpx.real / PRZEKLADNIA, i_cpx.imag / PRZEKLADNIA)
|
||||
u_cpx = complex(u_cpx.real / PRZEKLADNIA_NAPIECIA, u_cpx.imag / PRZEKLADNIA_NAPIECIA)
|
||||
|
||||
i_mag_sq = i_cpx.real**2 + i_cpx.imag**2
|
||||
if i_mag_sq < 1e-9: # Zabezpieczenie przed dzieleniem przez zero
|
||||
return 0.0, 0.0
|
||||
@@ -210,6 +249,8 @@ for i in range(N, len(t)):
|
||||
u2_re, u2_im = fcdft(window_u2)
|
||||
u3_re, u3_im = fcdft(window_u3)
|
||||
|
||||
# Konwersja do wartości wtórnych (dla calculate_impedance_from_raw)
|
||||
|
||||
# Tworzenie liczb zespolonych dla łatwiejszej matematyki symetrycznej
|
||||
I1_cpx = complex(i1_re, i1_im)
|
||||
I2_cpx = complex(i2_re, i2_im)
|
||||
|
||||
Reference in New Issue
Block a user