Releases: sq9fk/rotorpanel
Release list
1.12.6 — widoczny overlap: azymut i liczba ze znakiem
Azymut sam w sobie nie mówi, na którym okrążeniu stoi maszt: surowe 570 (+210) i surowe 210 (−150) pokazują ten sam kierunek 210°, a przy overlapie 180+360+180 dzieli je pełny obrót skrętu kabla. Róża kompasu nie ma jak tego pokazać.
Tabela ser2neta ma teraz kolumnę Pozycja z obiema liczbami: 210° / -150. Znak mówi, z której strony północy przyjechał maszt.
1.12.5 — karta nazywa przyczynę, nie objaw
Dwie rzeczy, które wyglądały identycznie i obie prowadziły w złe miejsce.
Sam nagłówek 0x57. 21 września jeden sterownik odsyłał na każde zapytanie jeden bajt 0x57 z opóźnieniem 182 ms ±6, przez godziny — bo był w trybie ręcznym zamiast A. Bajty przychodziły, więc karta świeciła na zielono "połączony" przy zupełnie martwym sterowaniu. Teraz po pięciu takich odpowiedziach z rzędu program mówi wprost: sprawdź tryb A (Auto).
Cisza, gdy nikt nie pyta. Przy rotorze o pozycję nie pytamy wcale — rytm nadaje program sterujący. Po zamknięciu PstRotatora karta meldowała "sterownik nie odpowiada X s" i zapalała parę na żółto, czyli wskazywała winnego, który nic nie zrobił. Teraz pisze "bezczynny — nikt nie odpytuje" i zostaje szara.
MainForm.OcenKarte wydzielona i sprawdzana w TestKarty — to ta decyzja myli się najczęściej.
1.12.4 — plik pułapki się obraca zamiast milknąć
Po przekroczeniu 2 MB zapis do podejrzane.txt po prostu ustawał, bez słowa — a ostatnia linia wyglądała tak samo jak koniec spokojnej sesji. 21 września trzy rotory zamilkły, 150 wpisów BRAK ODPOWIEDZI z pełnymi dziennikami wypełniło 2 MB w 2,5 godziny, plik zatrzymał się na 21:47, program chodził dalej.
- po limicie
podejrzane.txtwędruje dopodejrzane.1.txti zaczyna się nowy, - stary plik kończy się linią mówiącą, gdzie szukać dalej,
TestObrotuw harnessie sprawdza, że najnowszy wpis ląduje w pliku, do którego się zagląda.
1.12.3 — lista nastaw widoczna zawsze
10m fizycznie stanął na 208: w śladzie sterownika 250, 243, 237, 231, 225, 219, 212, a potem 57 02 00 08 20 powtórzone około pięćdziesiąt razy co do bajtu. To nie przekłamany odczyt — antena tam dojechała i stanęła. Po nastawie 0 ruszyła 208 → 360 krótszą drogą i zaparkowała, więc sterownik i mechanika są zdrowe. Pytanie brzmi: kto kazał jej jechać na 208 — a odpowiedzi nie było, bo lista nastaw żyła tylko w podejrzane.txt.
- rozbiór nastaw wychodzi spod wyłącznika diagnostyki: osiem ostatnich nastaw z godziną i znakiem ⚠ przy 208, w dymku ser2neta, zawsze,
- pusta lista jest odpowiedzią, nie brakiem odpowiedzi — znaczy, że przez mostek nic nie przeszło, i kieruje szukanie na drugiego klienta ser2neta albo panel sterownika,
- testy na cyfrach z dziennika (5400 → 180°, 3600 → 0°, 5680 → 208° ⚠).
1.12.2 — ustąpienie filtra pozycji przestaje być ciche
Po trzech odrzuceniach z rzędu filtr pozycji przyjmuje odczyt jako prawdziwy — to zabezpieczenie przed zablokowaniem filtra i zostaje. Do tej pory robił to bez śladu: w logu z 19 września jest jeden wpis ODRZUCONY ODCZYT: 252 -> 208, zawór pięciu sekund zjadł kolejne, a czwarty odczyt wszedł już jako prawdziwy i pojechał do PstRotatora.
FILTR USTĄPIŁtrafia dopodejrzane.txtz pominięciem zaworu pięciu sekund,- osobny licznik w dymku ser2neta: odrzucenie to „nie wierzymy", ustąpienie to „zmieniliśmy zdanie",
- test
Skad208.SprawdzOdpowiedzi: ramka57 02 00 08 20leży o jeden bit od 248° (bajt 2, bit 2,0x04 -> 0x00) — czyli od spodziewanego odczytu po 252°. Sklejka dwóch odpowiedzi nie daje jej w żadnym przypadku.
1.12.1 — kolumna „Odpowiedzi”: tabela sprawdza się sama
Pytanie z pierwszego przebiegu 1.12.0: „przy 11 000 zapytań pokazuje zero braków — czy to poprawne?”. Takie pytanie nie powinno wymagać rozmowy, więc tabela odpowiada na nie sama.
Port Rotor Stan Zapytań Odpowiedzi Braki % Czasy min/śr/max
──── ─────── ───────── ─────── ────────── ───── ──── ────────────────
4101 RAU A3S połączony 3217 3217 0 0,0% 282/301/657 ms
4102 RAK 15m połączony 3196 3193 3 0,1% 270/306/673 ms
4103 RAU 10m łączenie… — — — — —
Te trzy liczby pochodzą z trzech różnych miejsc kodu: zapytania rosną przy wysyłce ramki, odpowiedzi przy jej rozebraniu, braki przy porzuceniu zapytania starszego niż 700 ms. Jeśli zapytania = odpowiedzi + braki (z dokładnością do jednego zapytania w locie), licznik jest zdrowy i zero jest zerem.
Sprawdzone też mechanicznie: liczniki nie mają nic wspólnego z wyłącznikiem diagnostyki — wyłączenie podejrzane.txt gasi zbieranie buforów i dziennika, a nie liczenie wymian.
1.12.0 — wersja produkcyjna: diagnostyka na żądanie, tabela ser2net z procentami
Pułapka ramek jest domyślnie wyłączona. Włącza się ją w Ustawieniach polem Diagnostyka ramek (podejrzane.txt), a przełącznik działa od razu — żeby dało się zacząć zbierać w chwili, gdy usterka właśnie trwa. Przy wyłączonej diagnostyce nie powstaje nawet plik, a pompa nie kopiuje danych do buforów ani nie składa linii dziennika przy każdym kawałku.
Odrzucone odczyty pozycji liczą się zawsze i stoją w podpowiedzi ser2neta. Dane o położeniu anteny nie mogą znikać po cichu — licznik w interfejsie zastępuje wpis w pliku, nie znosi go.
Czerwona stopka tylko dla rotorów. Przy wzmacniaczu zgubiona odpowiedź nie znaczy nic, co dałoby się zrobić — SPE co jakiś czas po prostu nie odpowiada. To był fałszywy alarm.
Podpowiedź ser2neta to teraz tabela z procentami, rysowana czcionką o stałej szerokości:
Port Rotor Stan Zapytań Braki % Czasy min/śr/max
──── ─────── ───────── ─────── ───── ──── ────────────────
4101 RAU A3S połączony 3217 0 0,0% 282/301/657 ms
4102 RAK 15m połączony 3196 3 0,1% 270/306/673 ms
4103 RAU 10m łączenie… — — — —
1.11.51 — cofnięcie próby z oszczędzaniem pamięci
Wyłącznik zrobił dokładnie to, po co był: obalił własną zmianę w jednym przebiegu.
| czas | zwłoka | zastoje / 40 s | odśmiecenia gen0 / 40 s |
|---|---|---|---|
| 08:58:00 | 158 ms | +9,2 | +6,5 |
| 08:58:42 | 159 ms | +6,7 | +5,7 |
| 08:59:18 | 281 ms | +1,1 | +6,7 |
| 08:59:57 | 593 ms | +1,0 | +6,1 |
Odśmiecanie stoi jak wryte, zastoje spadają dziewięciokrotnie. Gdyby to śmieci robiły zastoje, obie kolumny szłyby razem. Do tego magnitudy się nie zgadzają: sześć odśmieceń gen0 na czterdzieści sekund, każde poniżej milisekundy, nie da dziewięciu przerw po 150–350 ms.
Mocniejszy wniosek: to prawdopodobnie w ogóle nie jest nasz kod — obciążenie było stałe, a zastoje spadły z dziewięciu na jeden, więc coś na maszynie było zajęte i się uspokoiło.
Usunięte: przełącznik, flaga w rotory.json, obie ścieżki bez kopii i odkładane formatowanie dziennika. Zostają liczniki odśmieceń gen0/gen1/gen2 w opisie czujnika zastoju — kosztują jedno wywołanie, a to one rozstrzygnęły sprawę.
1.11.50 — próba z wyłącznikiem: mniej alokacji w gorącej ścieżce
Po 1.11.49 zapis jest czysty: 0 ms, zapisow niepelnych 0, porzuconych bajtow 0, czekanie na uchwyt 0-24 ms. A kawałek i tak potrafi przeczekać w kolejce 221-885 ms — i przy najdłuższym z nich zastój procesu wypadł 0,0 s wcześniej.
To hipoteza, nie ustalenie, i stąd forma: zmiana ma wyłącznik w Ustawieniach („Oszczędzaj pamięć w mostkach") działający od razu, bez restartu, oraz flagę oszczedzajBufory w rotory.json. Do każdego wpisu pułapki dochodzą liczniki odśmieceń gen0/gen1/gen2 i informacja, czy oszczędzanie było włączone — żeby dało się porównać dwa przebiegi zamiast dyskutować.
Co oszczędzamy: odczyt pisze wprost do bufora pompy; zapis oddaje ten sam bufor, gdy idzie w całości; dziennik pułapki przy wzmacniaczu odkłada formatowanie. Przy rotorach zostaje po staremu, bo tam opis wymaga całego kawałka.
Uwaga: FILE_FLAG_OVERLAPPED tego nie naprawi — zwłoka nie siedzi już w wejściu-wyjściu, tylko w szeregowaniu wątków.
1.11.49 — limit czasu zapisu 200 ms, reszta kawałka porzucana
Rozdzielenie pomiaru dało odpowiedź w jednym wpisie:
ostatni zapis 431 B w 4542 ms, czekanie na uchwyt 32 ms
32 ms kontra 4542. Kolejność dostępu z 1.11.45 działa — blokada siedzi w samym WriteFile. Drugi wpis pokazuje skutek: 14 B w 0 ms, ale 11 kawałków w kolejce i 2748 ms zwłoki: jeden zablokowany zapis, za nim korek, potem wszystko spływa naraz.
Zatkania nie da się wykryć pytaniem o kolejkę — próg na cbOutQue z 1.11.46 nie zadziałał ani razu; przy zapisie stojącym 4542 ms licznik porzuconych został na zerze. com0com nie buforuje i nie zgłasza zatoru, tylko wstrzymuje zapis. Jedyne, co widać, to czas.
Stąd: WriteTotalTimeoutConstant z 2000 na 200 ms, cały kawałek ma na siebie 300 ms, potem reszta jest porzucana i liczona. Zgubiony kawałek obrazu jest tańszy niż zamrożony mostek — następna klatka przychodzi za ~95 ms.