„Manifest dla początkujących programistów o pokrewnych specjalnościach”, czyli jak doszedłem do tego momentu w życiu

Mój dzisiejszy artykuł to przemyślenia osoby, która na ścieżkę programowania trafiła niemal przez przypadek (aczkolwiek naturalnie).

Tak, rozumiem, że moje doświadczenie jest tylko moim doświadczeniem, ale wydaje mi się, że dobrze wpisuje się w ogólny trend. Co więcej, opisane poniżej doświadczenie odnosi się bardziej do dziedziny działalności naukowej, ale co tam, do cholery, nie żartuję - może się przydać na zewnątrz.

„Manifest dla początkujących programistów o pokrewnych specjalnościach”, czyli jak doszedłem do tego momentu w życiu
Źródło: https://xkcd.com/664/

Ogólnie rzecz biorąc, dedykowane wszystkim obecnym studentom od byłego studenta!

Oczekiwania

Kiedy w 2014 roku ukończyłem studia licencjackie na kierunku Technologie Informacyjne i Systemy Komunikacyjne, o świecie programowania nie wiedziałem prawie nic. Tak, jak wielu innych, zdałem przedmiot „informatyka” na pierwszym roku – ale, Panie, to było na pierwszym roku! To była wieczność!

W sumie nie spodziewałem się niczego szczególnego po studiach licencjackich, a wchodząc na studia magisterskie „Komunikacja i przetwarzanie sygnałów” Niemiecko-Rosyjski Instytut Nowych Technologii.

Ale na próżno...

Byliśmy dopiero drugim naborem, a chłopaki z pierwszego jeszcze pakowali walizki do dalekich Niemiec (staż trwa pół roku na drugim roku studiów magisterskich). Inaczej mówiąc, nikt z najbliższego otoczenia nie zetknął się jeszcze poważnie z metodami edukacji europejskiej i nie było kogo dopytywać o szczegóły.

Na pierwszym roku mieliśmy oczywiście różnego rodzaju praktyki, w których zazwyczaj demokratycznie oferowano nam wybór pomiędzy pisaniem skryptów (głównie w języku MATLAB), a używaniem różnych wysoce wyspecjalizowanych GUI (w tym sensie, że bez pisania skryptów – symulacja środowiska modelowania).

„Manifest dla początkujących programistów o pokrewnych specjalnościach”, czyli jak doszedłem do tego momentu w życiu

Nie trzeba dodawać, że my, przyszli mistrzowie nauk ścisłych, przez naszą młodzieńczą głupotę unikaliśmy pisania kodu jak ognia. Tutaj jest na przykład Simulink z MathWorks: tu są bloki, tu są połączenia, tu są wszelkiego rodzaju ustawienia i przełączniki.

Pogląd, który jest natywny i zrozumiały dla osoby, która wcześniej pracowała przy projektowaniu obwodów i inżynierii systemów!

„Manifest dla początkujących programistów o pokrewnych specjalnościach”, czyli jak doszedłem do tego momentu w życiu
Źródło: https://ch.mathworks.com/help/comm/examples/parallel-concatenated-convolutional-coding-turbo-codes.html

Tak nam się wydawało...

Rzeczywistość

Jedną z praktycznych prac pierwszego semestru było opracowanie transceivera sygnału OFDM w ramach przedmiotu „Metody modelowania i optymalizacji”. Pomysł jest bardzo udany: technologia jest nadal aktualna i dość popularna ze względu na jej zastosowanie na przykład w sieciach Wi-Fi i LTE/LTE-A (w postaci OFDMA). To najlepsza rzecz dla mistrzów, aby ćwiczyć swoje umiejętności w modelowaniu systemów telekomunikacyjnych.

„Manifest dla początkujących programistów o pokrewnych specjalnościach”, czyli jak doszedłem do tego momentu w życiu

A teraz dostajemy kilka opcji specyfikacji technicznych z oczywiście niepraktycznymi parametrami ramy (żeby nie szukać rozwiązania w internecie) i rzucamy się na wspomnianego już Simulinka... I dostajemy po głowie czajnikiem rzeczywistości:

  • Każdy blok jest obarczony wieloma nieznanymi parametrami, które strach zmienić za jednym zamachem.
  • Manipulacje liczbami muszą być wykonane, wydaje się, proste, ale nadal trzeba się męczyć, nie daj Boże.
  • Maszyny katedralne zauważalnie spowalniają od szaleńczego korzystania z GUI, nawet na etapie surfowania po bibliotekach dostępnych bloków.
  • Aby dokończyć coś w domu, musisz mieć tego samego Simulinka. I tak naprawdę nie ma alternatywy.

Tak, w końcu oczywiście zakończyliśmy projekt, ale zakończyliśmy go z głośnym westchnieniem ulgi.

Minęło trochę czasu i dotarliśmy do końca pierwszego roku studiów magisterskich. Ilość zadań domowych z wykorzystaniem graficznych interfejsów użytkownika zaczęła spadać proporcjonalnie do wzrostu odsetka uczniów z języka niemieckiego, chociaż nie osiągnęła ona jeszcze punktu zmiany paradygmatu. Wielu z nas, w tym ja, pokonując swoje znaczne amplitudy w budowaniu, coraz częściej używało Matlaba w naszych projektach naukowych (choć w formie Toolboxów), a nie pozornie znajomego Simulinka.

Naszą wątpliwość wzbudziła wypowiedź jednego ze studentów drugiego roku (który właśnie wtedy wrócił do Rosji):

  • Zapomnij, przynajmniej na czas stażu, o Similinku, MathCad i innych LabView - za górkę wszystko jest napisane w MATLABIE, przy użyciu samego MatLaba lub jego darmowej „wersji” Octave.

Stwierdzenie okazało się po części prawdziwe: w Ilmenau również spór o dobór narzędzi nie został do końca rozstrzygnięty. To prawda, wybór padł głównie pomiędzy MATLAB-em, Pythonem i C.

Jeszcze tego samego dnia ogarnęła mnie naturalna ekscytacja: czy nie powinienem przenieść mojej części modelu nadajnika OFDM na formę skryptową? Dla żartu.

I zabrałem się do pracy.

Krok po kroku

Zamiast teoretycznych obliczeń podam po prostu link do tego doskonały artykuł 2011 od tgx i na zjeżdżalniach Warstwa fizyczna LTE profesorowie Michel-Tila (TU Ilmenau). Myślę, że to wystarczy.

„A więc” – pomyślałem – „powtórzmy, co będziemy modelować?”
Będziemy modelować Generator ramek OFDM (Generator ramek OFDM).

Co będzie zawierać:

  • symbole informacyjne
  • sygnały pilota
  • zera (DC)

Z czego (dla uproszczenia) abstrahujemy:

  • z modelowania prefiksu cyklicznego (jeśli znasz podstawy, dodanie go nie będzie trudne)

„Manifest dla początkujących programistów o pokrewnych specjalnościach”, czyli jak doszedłem do tego momentu w życiu

Schemat blokowy rozważanego modelu. Zatrzymamy się na odwrotnym bloku FFT (IFFT). Żeby dopełnić obrazu, resztę każdy może sam dokończyć – obiecałem nauczycielom z wydziału, że coś zostawią uczniom.

Zdefiniujmy je sami. ćwiczenia:

  • stała liczba podnośnych;
  • stała długość ramy;
  • musimy dodać jedno zero na środku i parę zer na początku i na końcu ramki (w sumie 5 sztuk);
  • symbole informacyjne są modulowane przy użyciu M-PSK lub M-QAM, gdzie M jest porządkiem modulacji.

Zacznijmy od kodu.

Cały skrypt można pobrać ze strony powiązanie.

Zdefiniujmy parametry wejściowe:

clear all; close all; clc

M = 4; % e.g. QPSK 
N_inf = 16; % number of subcarriers (information symbols, actually) in the frame
fr_len = 32; % the length of our OFDM frame
N_pil = fr_len - N_inf - 5; % number of pilots in the frame
pilots = [1; j; -1; -j]; % pilots (QPSK, in fact)

nulls_idx = [1, 2, fr_len/2, fr_len-1, fr_len]; % indexes of nulls

Teraz wyznaczamy indeksy symboli informacyjnych, przyjmując założenie, że sygnały pilotujące muszą koniecznie występować przed i/lub po zerach:

idx_1_start = 4;
idx_1_end = fr_len/2 - 2;

idx_2_start = fr_len/2 + 2;
idx_2_end =  fr_len - 3;

Następnie pozycje można określić za pomocą funkcji linspace, redukując wartości do najmniejszej z najbliższych liczb całkowitych:

inf_idx_1 = (floor(linspace(idx_1_start, idx_1_end, N_inf/2))).'; 
inf_idx_2 = (floor(linspace(idx_2_start, idx_2_end, N_inf/2))).';

inf_ind = [inf_idx_1; inf_idx_2]; % simple concatenation

Dodajmy do tego indeksy zer i posortujmy:

%concatenation and ascending sorting
inf_and_nulls_idx = union(inf_ind, nulls_idx); 

W związku z tym wskaźniki sygnału pilotażowego to wszystko inne:

%numbers in range from 1 to frame length 
% that don't overlape with inf_and_nulls_idx vector
pilot_idx = setdiff(1:fr_len, inf_and_nulls_idx); 

Teraz zrozumiemy sygnały pilotażowe.

Mamy szablon (zmienna piloci) i powiedzmy, że chcemy, aby piloty z tego szablonu były kolejno wstawiane do naszej ramki. Oczywiście można to zrobić w pętli. Można też pobawić się trochę z macierzami - na szczęście MATLAB pozwala na to z wystarczającym komfortem.

Najpierw określmy, ile z tych szablonów mieści się całkowicie w ramce:

pilots_len_psudo = floor(N_pil/length(pilots));

Następnie tworzymy wektor składający się z naszych szablonów:

% linear algebra tricks:
mat_1 = pilots*ones(1, pilots_len_psudo); % rank-one matrix
resh = reshape(mat_1, pilots_len_psudo*length(pilots),1); % vectorization

I definiujemy mały wektor, który zawiera tylko fragment szablonu - „ogon”, który nie mieści się całkowicie w ramce:

tail_len = fr_len  - N_inf - length(nulls_idx) ...
                - length(pilots)*pilots_len_psudo; 
tail = pilots(1:tail_len); % "tail" of pilots vector

Otrzymujemy postacie pilotażowe:

vec_pilots = [resh; tail]; % completed pilots vector that frame consists

Przejdźmy do symboli informacyjnych, czyli uformujemy przekaz i będziemy go modulować:

message = randi([0 M-1], N_inf, 1); % decimal information symbols

if M >= 16
    info_symbols = qammod(message, M, pi/4);
else
    info_symbols = pskmod(message, M, pi/4);
end 

Wszystko jest gotowe! Montaż ramy:

%% Frame construction
frame = zeros(fr_len,1);
frame(pilot_idx) = vec_pilots;
frame(inf_ind) = info_symbols

Powinieneś otrzymać coś takiego:

frame =

   0.00000 + 0.00000i
   0.00000 + 0.00000i
   1.00000 + 0.00000i
  -0.70711 - 0.70711i
  -0.70711 - 0.70711i
   0.70711 + 0.70711i
   0.00000 + 1.00000i
  -0.70711 + 0.70711i
  -0.70711 + 0.70711i
  -1.00000 + 0.00000i
  -0.70711 + 0.70711i
  -0.70711 - 0.70711i
   0.00000 - 1.00000i
   0.70711 + 0.70711i
   1.00000 + 0.00000i
   0.00000 + 0.00000i
   0.00000 + 1.00000i
   0.70711 - 0.70711i
  -0.70711 + 0.70711i
  -1.00000 + 0.00000i
  -0.70711 + 0.70711i
   0.70711 + 0.70711i
   0.00000 - 1.00000i
  -0.70711 - 0.70711i
   0.70711 + 0.70711i
   1.00000 + 0.00000i
   0.70711 - 0.70711i
   0.00000 + 1.00000i
   0.70711 - 0.70711i
  -1.00000 + 0.00000i
   0.00000 + 0.00000i
   0.00000 + 0.00000i

"Rozkosz!" — pomyślałem zadowolony i zamknąłem laptopa. Wszystko zajęło mi kilka godzin: łącznie z pisaniem kodu, nauką niektórych funkcji Matlaba i myśleniem o sztuczkach matematycznych.

Jakie wnioski wtedy wyciągnąłem?

Subiektywny:

  • Pisanie kodu jest przyjemne i bliskie poezji!
  • Skrypty są najwygodniejszą metodą badawczą w dziedzinie komunikacji i przetwarzania sygnałów.

Cel:

  • Do wróbli nie trzeba strzelać z armaty (chyba, że ​​taki cel edukacyjny jest oczywiście tego wart): korzystając z Simulinka, podjęliśmy się rozwiązania prostego problemu za pomocą wyrafinowanego narzędzia.
  • GUI jest dobre, ale lepsze jest zrozumienie tego, co kryje się „pod maską”.

A teraz, będąc dalekim od bycia studentem, chcę powiedzieć wspólnocie studenckiej, co następuje:

  • Bądź dobrej myśli!

Spróbuj napisać kod, nawet jeśli na początku będzie zły. W programowaniu, jak w każdej innej działalności, najtrudniejszy jest początek. I lepiej zacząć wcześniej: jeśli jesteś naukowcem lub nawet technikiem, prędzej czy później będziesz potrzebować tej umiejętności.

  • Żądanie!

Wymagaj od nauczycieli i przełożonych postępowego podejścia i narzędzi. Jeśli jest to oczywiście możliwe...

  • Tworzyć!

Gdzie indziej lepiej pokonać wszystkie rany początkującego, jeśli nie w ramach programu edukacyjnego? Twórz i doskonal swoje umiejętności – im szybciej zaczniesz, tym lepiej.

Aspirujący programiści ze wszystkich krajów, łączcie się!

PS

Aby utrwalić moją bezpośrednią relację ze studentami, załączam pamiętne zdjęcie z 2017 roku z dwoma rektorami: Peterem Scharffem (po prawej) i Albertem Kharisovichem Gilmutdinovem (po lewej).

„Manifest dla początkujących programistów o pokrewnych specjalnościach”, czyli jak doszedłem do tego momentu w życiu

Choćby dla tych kostiumów warto było ukończyć program! (żartuję)

Źródło: www.habr.com

Dodaj komentarz