1 - Zbiór wiedzy do Matlaba i Simulinka

Zestaw poradników, assetów, presetów i innych przydatnych rzeczy do Matlaba i Simulinka kierowanych pod budowę bolidu autonomicznego

Matlab & Simulink

W tym miejscu znajdziesz wszystkie poradniki i “gotowce”, które mogą się okazać przydatne podczas nauki i pracy z Matlabem i Simulinkiem.

Słowo wstępu

Na początku zanim przystąpisz do pracy w Matlabie i/lub Simulinku musisz się zaopatrzyć w sam program i licencję. Jako student PRz masz dostęp do licencji akademickiej, która udostępnia Ci wszystkie najpotrzebniejsze apki do Matlaba. Poradnik jak aktywować taką licencję znajdziesz w linku poniżej. Jeśli chodzi o apki wybierane podczas instalacji, to głównie będziesz korzystał ze wszystkiego powiązanego z Simulinkiem, bibliotek Simscape i blocksetów (np: Powertrain Blockset). Najbezpieczniej jednak będzie podczas instalacji samego Matlaba zaznaczyć wszystkie apki, kto wie co jeszcze może okazać się przydatne ;). Jeśli okaże się, że jakiejś apki brakuje, można ją doinstalować z poziomu samego Matlaba.

Licencja, Instalacja Matlaba i modułów

Oficjalne tutoriale, dokumentacje i zapisy webinarów

Oficjalne presety, modele i repozytoria.

Tutoriale społecznościowe

2 - Dokumentacja Symulatora Okrążenia

Tutaj znajdują się instrukcje jak korzystać z symulacji okrążenia wyścigowego w środowisku Matlab.

Wstęp

W wypisanych poniżej podstronach znajdują się elementy dokumentacji zawierające informacje o poszczególnych jej elementach, ułożone wedle elementu bolidu (opony, układ napędowy etc.). Symulacja NIE jest naszego autorstwa, oryginalni autorzy to zespół Baltic Racing.

Linki do repozytorium:
Oryginał: Repozytorium Baltic Racing

Wraz z postępem prac dokumentacja będzie aktualizowana.

2.1 - paramtery akumulatora

działanie/obliczanie zmiennych akumulaotra

Wstęp

calculateAccumulatorData.m - jest to opisywany plik

DZIAŁANIE PLIKU

  1. pierwsze 4 linie służą do ładowania danych z plików MAT do zmiennych w skrypcie.

  2. Następnie zapisane są funkcje, które służą do liczenia poszczególnych danych.

Accumulator.V_i(i) = sum(Accumulator.Voltage_Cellpack(:,i)); - Oblicza sumę napięć wszystkich ogniw w akumulatorze dla danego punktu czasowego (i), przechowuje tę wartość w Accumulator.V_i(i).

Accumulator.A_accu_cell(i) = P_el(i) / Accumulator.V_i(i) / setup.nZellen_Parallel; - Oblicza prąd akumulatora dla danego punktu czasowego (i) korzystając z mocy elektrycznej (P_el), napięcia (Accumulator.V_i(i)) i liczby ogniw równoległych (setup.nZellen_Parallel).

Accumulator.Current_Cellpack_Pointer(i) - Określa wskaźnik aktualnego prądu dla pakietu ogniw w 0,1A na podstawie mocy elektrycznej i napięcia.

Warunki “if” sprawdzają i ograniczają wartość Accumulator.Current_Cellpack_Pointer(i) w określonym zakresie.

Accumulator.VirtualCurrent_Cellpack(i) - Oblicza wirtualny prąd dla pakietu ogniw na podstawie skorygowanych danych rozładowania.

Accumulator.Energy_Cellpack(i) - Oblicza zużycie energii dla pakietu ogniw w jednostkach Ah na podstawie wirtualnego prądu i czasu.

Accumulator.Energy_Cellpack_Total(i+1) - Sumuje całkowite zużycie energii do tego punktu czasowego.

Accumulator.Capacity_Cellpack(1:131,i+1) - Aktualizuje pojemność pakietu ogniw na podstawie zużycia energii.

Accumulator.SOC_Cellpack(1:131,i+1) - Oblicza stan naładowania (SOC) pakietu ogniw na podstawie aktualnej i początkowej pojemności.

Accumulator.SOC_Pointer(1:131,i+1) - Określa wskaźnik SOC w milicentylach na podstawie obliczonego SOC.

Accumulator.Current_Cellpack_Pointer_Voltage(1,i+1) - Określa wskaźnik napięcia pakietu ogniw na podstawie obliczonego wskaźnika prądu.

Kolejne dwa warunki if ograniczają wartości wskaźnika napięcia i SOC do dopuszczalnego zakresu.

W bloku try-catch jest próba dostępu do danych napięcia pakietu ogniw na podstawie obliczonych wskaźników prądu i SOC. Jeśli operacja się nie powiedzie, kod nie rzuca błędem.

2.2 - paramtery akumulatora

interfejs do wprowadzania zmiennych akumulatora

Wstęp

Interfejs i jego oddziaływanie poszczególnych danych. Dany plik zaprojektowany jest w App Designer i jest podzielony na Design View oraz Code View

Działanie

  1. Uruchomienie aplikacji:

Gdy aplikacja zostaje uruchomiona, jej konstruktor “Accumulator” jest wywoływany. Tworzy on interfejs użytkownika poprzez wywołanie metody createComponents. Następnie uruchamiana jest funkcja startupFcn, która inicjuje działanie aplikacji poprzez załadowanie danych, obliczenie i wyświetlenie pojemności akumulatora oraz zmianę schematu kolorów interfejsu.

AccumulatorSetupUIFigure: Główne okno aplikacji.

AccumulatorPanel: Panel zawierający wszystkie komponenty interfejsu użytkownika związane z akumulatorem.

Przyciski: SaveButton, ResetButton, DeleteCellButton, SaveCellButton.

Pola edycji numerycznej: NominalVoltageVEditField, CellCapacitymAhEditField, CellsInParallelEditField, CellsInRowEditField, itp.

Etykiety: OverallCapacityLabel, NumberofCellsLabel, OverallCellWeightLabel, AccumulatorVoltageLabel, itp.

SelectCellDropDown: Lista rozwijana umożliwiająca wybór typu ogniwa.

CellDataPanel: Panel zawierający dane dotyczące pojedynczego ogniwa.

app.CallingApp = mainapp;

loadData(app) – Wczytuje dane z aplikacji głównej

updateCapacity(app) – aktualizuje całkowitą pojemność akumulatora

changeColorScheme(app) – wiele zmiennych obsługujących zmiane kolorów interfejsu

  1. Zamykanie aplikacji:

Gdy użytkownik próbuje zamknąć aplikację, wywoływana jest funkcja zwrotna AccumulatorSetupUIFigureCloseRequest, która zapisuje dane i usuwa aplikację.

  1. Wprowadzanie danych:

Wartości wprowadzone przez użytkownika, takie jak pojemność ogniwa, liczba ogniw w rzędzie i równolegle, są automatycznie aktualizowane poprzez funkcje zwrotne, takie jak CellCapacitymAhEditFieldValueChanged czy CellsinrowEditFieldValueChanged. Po zmianie tych danych, wywoływana jest funkcja updateCapacity, która aktualizuje wyświetlane wartości związane z pojemnością akumulatora.

  1. Podsumowanie

Interfejs umożliwia użytkownikwi prowadzanie danych dotyczących akumulatora, ich zapisywanie, resetowanie oraz prezentuje obliczone wartości. Dodatkowo, interfejs jest dostosowywany do zdefiniowanego schematu kolorów.

2.3 - calculateSteeringData

Funkcja służąca do obliczenia kątów skrętu, odchylenia, kierownicy, obrotu odchylenia i ackermanna

Opisany plik: calculateSteeringData.m

Wywoływanie funkcji i wartości które zwraca

Funkcja przyjmuje 16 parametrów:

wheelbase - rozstaw osi
R - promień łuku
lr - odległość tylnej osi od środka masy
lf - odległość przedniej osi od środka masy
vV - prędkość bolidu
FWZ_fl, FWZ_rl, FWZ_fr, FWZ_rr - nacisk na poszczególne opony (nieużywane)
track_f - szerokość toru
cZ_fl, cZ_fr, cZ_rl, cZ_rr - interpolowane sztywności poszczególnych opon (nieużywane)
alpha_f - kąt poślizgu przedniej osi
alpha_r - kąt poślizgu tylnej osi

Funkcja zwraca 14 parametrów:

delta - kąt skrętu
beta - kąt odchylenia (Schwimmwinkel)
psi1 - obrót odchylenia (Gierrate)
alpha_f, alpha_r - kąty poślizgu osi
alpha_fr, alpha_fl, alpha_rr, alpha_rl - kąty poślizgu poszczególnych opon
delta_fl - kąt skrętu lewego koła
delta_fr - kąt skrętu prawego koła
delta_sw - kąt skrętu kierownicy
ackermann - "Kąt Ackermanna to geometria związana z układem kierowniczym pojazdu, która określa różnicę w kącie skrętu pomiędzy przednimi kołami w momencie skręcania."
ackermannPercent - ackermann w wartości procentowej

Kąt odchylenia i obrót odchylenia grafika poglądowa

Kąt odchylenia i obrót odchylenia grafika poglądowa

Ackermann grafika poglądowa

Ackermann grafika poglądowa

Działanie funkcji

Sprawdzenie kierunku skrętu:

%%Sprawdzenie kierunku zakrętu, gdy R jest dodatnie - skręt w prawo
 if R > 0
        f = -1;
    else
        f = 1;
    end

Obliczanie kątów skrętu, odchylenia, kierownicy i obrotu odchylenia:

delta = wheelbase/1000/R;  
%kąt skrętu (dzielenie przez 1000 w celu konwersji na metry)

beta = f*atan((lr/1000)/sqrt(R^2-(lr/1000)^2)); 
%kąt odchylenia

psi1 = vV/R;
%kąt obrotu odchylenia

delta_sw = delta * 180/pi * 5.093;
%kąt skrętu kierownicy (5.093 to mnożnik zależny od układu kierowniczego)

Obliczanie kątów skrętu dla koła wewnętrznego i zewnętrznego:

if R > 0    %Gdy R jest dodatnie - skręt w prawo, a prawe koło jest wewnętrznym do łuku
    delta_fl = atan((wheelbase/1000)/(R+(track_f/1000/2)));     %kąt skrętu lewego koła
    delta_fr = atan((wheelbase/1000)/(R-(track_f/1000/2)));     %kąt skrętu lewego koła

    ackermann = atan(wheelbase/((wheelbase/tan(delta_fl))-track_f));    %wartość ackermanna
    ackermannPercent = delta_fr/ackermann*100;  %procentowa wartość ackermanna
else
    delta_fl = atan((wheelbase/1000)/(R-(track_f/1000/2))); 
    delta_fr = atan((wheelbase/1000)/(R+(track_f/1000/2)));           

    ackermann = atan(wheelbase/((wheelbase/tan(delta_fr))-track_f));
    ackermannPercent = delta_fl/ackermann*100;                       
end  

2.4 - Inicjalizacja powtórki symulacji

initializeSimulationReplay.m

Wstęp

Przebieg inicjalizacji powtórki symulacji w pliku initializeSimulationReplay.m

Funkcja initalizeSimulationReplay()

Opisywane niżej linie są wykresami prezentującymi trasę przejechaną przez bolid w trakcie symulacji.
Na początku funkcja ładuje plik z zapisem symulacji przejazdu oraz czyści linie wyświetlane w interfejsie.

Następnie na elemencie app.RunNumberSpinner program próbuje wykonać poniższe operacje (zablokować interakcje z nim oraz ustawić jego wartość na 1). Jeśli wystąpi jakiś błąd i nie będzie się tego dało zrobić to jest włączany oraz jego zakres jest zmieniany na od 1 do ilości przejazdów.


RunNumberSpinner

RunNumberSpinner

drawPedalPlots() - tworzy elementy obrazujące nacisk pedałów. Deklaracja funkcji na końcu pliku.

Następnie ustawiane są kolory zależne od wybranego motywu.

Funkcja hold() z parametrem ‘on’ sprawia, że kolejne rysowane linie nie wymazują poprzednich. Następnie na GUI są przeprowadzane poniższe operacje:

Do struktory o nazwie saveFileData przypisywane są wszystkie wartości z wybranego wcześniej pliku z zapisem przejazdu (saveFile), żeby później te informacje zostały wpisane do elementów GUI (app.DropDown).

Wykonując poniższe funkcje program kolejno:
-zmienia limity rysowania linii
-rysuje zaznaczone w checkboxach rodzaje linii
-rysuje apexy jeśli odpowiedni checkbox jest zaznaczony

gdzie:

gdzie:


Parametr ‘app’ - aplikacja
Parametr ‘1’ - numer przejazdu
Parametr ‘saveFile’ - result; plik z zapisem telemetrii

Funkcja drawPedalPlots()

Ustawia właściwości elementów obrazujących nacisk pedałów.

Funkcja recordPedalPlot()

Pobierając plik z telemetrią ustawia wartości elementów obrazujących nacisk pedałów.

2.5 - Inicjowanie Opon do symulacji

Wdrożenie parametrów opon do symulacji LapSim (plik LoadTIR.m)

Wstęp

Plik LoadTIR.m umożliwia załadowanie pliku z danymi opony do symulacji. Wszystkie odniesienia do danej linii kodu odnoszą się do pliku dostępnego w oryginalnym repozytorium, bez żadnych uprzednich modyfikacji kodu.

Wybór pliku

Plik rozpoczyna sie deklaracją funkcji loadTIR z parametrem w postaci lokalizacji pliku zawierającego parametry opony. Parametr ten pojawia się także w plikach Conti_Tire_Plots zarówno dla obliczeń w płaszczyźnie wzdłużnej i poprzecznej, a także w pliku Find_maximum_corner_speed. Celem modyfikacji rodzaju opony konieczne będzie dostosowanie kodu, aby możliwy był wybór większej ilości opon i przeprowadzenia obliczeń na ich parametrach.

Rys.1 Odwołania do lokalizacji pliku z parametrycznym opisem opony

Rys.1 Odwołania do lokalizacji pliku z parametrycznym opisem opony

Następnie w linii 7 plik jest otwierany w trybie tylko do odczytu i inicjowane są dwie zmienne pełniące funkcję liczników.

Inicjacja parametrów

Rys.2 Fragment kodu zczytujący parametry opon z pliku

Rys.2 Fragment kodu zczytujący parametry opon z pliku

W pętli działającej do momentu zakończenia pliku zawierającego parametry zczytywane są kolejne parametry. Osobno przetwarzając każdą linijkę pliku. W pierwszej kolejności sprawdzane jest, czy dana linia kodu nie jest komentarzem bądź tytułem. korzystając z ustandaryzowanego sposobu wpisywania parametrów kolejne dane i ich nazwy są zczytywane i zapisywane do pamięci. Po zczytaniu danych plik jest zamykany i niepotrzebne dane są usuwane z pamięci.

Sprawdzenie masy

Rys.3 Podmiana masy

Rys.3 Podmiana masy

Ze względu na konflikt nazw zmiennych podmieniana jest nazwa zmiennej opisującej masę na nazwę pomocniczą.

Generowanie opon

Korzystając z pobranych wcześniej danych generowana jest parametryczna struktura opony.

Rys.4 Generowanie opon

Rys.4 Generowanie opon

Program przepisuje odczytane wcześniej dane do formatu właściwego, który ułatwia pracę nad danymi. Sprawdzane jest między innymi, czy odczytywana wartość ma format tekstowy czy liczbowy.

Rys.5 Dodawanie opisów opon

Rys.5 Dodawanie opisów opon

Finalnie zapisane dane są opisywane korzystając z nazw zmiennych.

2.6 - paramtery układu napędowego

interfejs do wprowadzania zmiennych układu napędowego

Wstęp

Interfejs i jego oddziaływanie poszczególnych danych. Dany plik zaprojektowany jest w App Designer i jest podzielony na Design View oraz Code View

DrivetrainSetupUIFigure: Objekt reprezentujący figurę w UI PowertrainDataPanel: Panel przedstawiający dane o układzie napędowym UITable: Tablica przedstawiająca tablicę w UI idle_rpm1minEditField: Miejsce do edytowania obrotów na luzie TorquemultiplierEditField: Miejsce do edytowania mnożnika momentu obrotowego n_max1minEditField: Miejsce do edycji maksymalnych obrotów DrivetrainEfficencyEditField: Miejsce do edycji efektywności układu napędowego LayoutDropDown: Rozwijane UI do wyboru układu LayoutDropDownLabel: Etykieta do rozwijanego elemntu UI PowertrainSwitch: Przycisk do wyboru układu napędowego EPowertrainParametersPanel: Panel zawierający parametry elektryczne układu napędowego InverterEfficiencyEditField: Miejsce do edycji efektywności falownika PowerlimitWEditField: Miejsce do edycji limitu mocy w watach DeleteEngineButton: Przycisk, który usuwa parametry silnika EnginePresetDropDown: Rozwijany element UI do wybory presetów silnika Panel_2: Obiekt reprezentujący panel. z_chaindriveEditField: Obiekt NumericEditField reprezentujący pole edycji dla napędu łańcuchowego. z_sprocketEditField: Obiekt NumericEditField reprezentujący pole edycji dla zębatki. ChaindriveSingleGearsetCheckBox: Obiekt CheckBox reprezentujący pole wyboru dla pojedynczego układu napędowego łańcuchowego. loadPanel: Obiekt Panel reprezentujący panel dla obciążenia. TY20BaselineButton: Obiekt Button reprezentujący przycisk dla podstawowej konfiguracji TY20. SaveButton: Obiekt Button reprezentujący przycisk do zapisu. ResetButton: Obiekt Button reprezentujący przycisk do resetowania. ElectricBaselineButton: Obiekt Button reprezentujący przycisk dla podstawowej konfiguracji elektrycznej. TY19BaselineButton: Obiekt Button reprezentujący przycisk dla podstawowej konfiguracji TY19. ChaindrivePanel: Obiekt Panel reprezentujący panel dla napędu łańcuchowego. i_PEditField: Obiekt NumericEditField reprezentujący pole edycji dla i_P. GearboxPanel: Obiekt Panel reprezentujący panel dla skrzyni biegów. n_downshift1minEditField: Obiekt NumericEditField reprezentujący pole edycji dla obrotów przy redukcji biegów. EnableGearboxCheckBox: Obiekt CheckBox reprezentujący pole wyboru dla włączenia skrzyni biegów. PlotGearboxdataButton: Obiekt Button reprezentujący przycisk do generowania wykresu danych skrzyni biegów. GearboxTable: Obiekt Table reprezentujący tabelę dla danych skrzyni biegów. Button_4: Obiekt Button reprezentujący kolejny przycisk. Button_3: Obiekt Button reprezentujący jeszcze jeden przycisk. n_shift1minEditField: Obiekt NumericEditField reprezentujący pole edycji dla obrotów przy zmianie biegów. t_shiftsEditField: Obiekt NumericEditField reprezentujący pole edycji dla czasu zmiany biegów. UIAxes3: Obiekt UIAxes reprezentujący osie do generowania wykresów. UIAxes2: Obiekt UIAxes reprezentujący kolejne osie do generowania wykresów. UIAxes: Obiekt UIAxes reprezentujący jeszcze inne osie do generowania wykresów.

Klasa Drivetrain reprezentuje obiekt odpowiedzialny za aktualizację wykresu dla krzywych momentu i mocy silnika.

  • Obiekt głównej aplikacji
CallingApp   
  • Metoda updateMotorGraph(app) aktualizuje wykresy dla jednego silnika. Metoda ta pobiera dane z tabeli UITable, oblicza moc i moment dla każdej wartości obrotów, a następnie rysuje wykresy dla momentu i mocy.

  • Aktualizuje etykietę przekładni i zwraca wartość przekładni

i_tot = updateGearRatio(app);
  • Pobiera wartość mnożnika momentu
torque_multiplier = app.TorquemultiplierEditField.Value;
  • Pobiera dane z tabeli UITable
data = app.UITable.Data;
  • Separuje dane na dwie 1D tablice, dodając 0 na początku, ponieważ obie osie powinny zaczynać się od zera
x = [1; data(:,1)]; n = RPM
y = [0; data(:,2)] * torque_multiplier; M = Moment
  • Oblicza moc silnika dla danej wartości obrotów i momentu
p = zeros(1:size(x,1));
for n = 1 : length(x)
p(n) = (y(n) * x(n)) / 9.5488 / 1000;
end
  • Czyści wykres UIAxes, aby można go było ponownie utworzyć
cla(app.UIAxes,'reset');
  • Ustawia osie
app.UIAxes.XLabel.String='RPM [1/min]';
yyaxis(app.UIAxes,'left'); 
  • Rysuje wykres momentu
plot(app.UIAxes,x,y);
  • Zatrzymuje wykres, aby można było narysować nową oś
hold(app.UIAxes);
title(app.UIAxes,"Single Motor");
yyaxis(app.UIAxes,'right');
app.UIAxes.YLabel.String='Moc [kW]';
  • Rysuje wykres mocy
plot(app.UIAxes,x,p);
  • Wyłącza możliwość przybliżania dla wykresu
disableDefaultInteractivity(app.UIAxes);
  • Sprawdza, który układ silnika jest wybrany i dostosowuje liczbę silników
Motorsdropdown = app.LayoutDropDown.Value;
if (Motorsdropdown == "2 Motor RWD")
    numberMotors = 2;
elseif (Motorsdropdown == "1 Motor RWD")
    numberMotors = 1;
elseif (Motorsdropdown == "AWD")
    numberMotors = 4;
end
  • Oblicza moment wytworzony przez daną liczbę silników
y_2 = y * numberMotors;
p_2 = zeros(1:length(x));
  • Oblicza moc silników dla danej wartości obrotów i momentu
for n = 1 : length(x)
p_2(n) = (y_2(n) * x(n)) / 9.5488 / 1000;
end
  • Czyści wykres UIAxes2, aby można go było ponownie utworzyć
cla(app.UIAxes2,'reset');
  • Metoda rysująca wykresy dla przekładni wtórnej. x - Tablica wartości osi X. y_2 - Tablica wartości osi Y dla momentu obrotowego. p_2 - Tablica wartości osi Y dla mocy.

  • Motorsdropdown - Wybrany rodzaj silnika.

(void)drawPlotsWithX:(NSArray *)x y_2:(NSArray *)y_2 p_2:(NSArray *)p_2 Motorsdropdown:(NSString *)Motorsdropdown {
  • Aktualizuje przekładnię wtórną.
return Wartość całkowitego przekładniowego stosunku.
(double)updateGearRatio
return i_tot;
  • Zmienia schemat kolorów aplikacji.
(void)changeColorScheme

-Poniżej znajdują się zmienne reprezentujące kolory i style aplikacji. PrimaryColor: Kolor podstawowy aplikacji. OnPrimaryColor: Kolor tekstu na tle PrimaryColor. PrimaryVariantColor: Wariant koloru podstawowego aplikacji. OnPrimaryVariantColor: Kolor tekstu na tle PrimaryVariantColor. SecondaryColor: Kolor drugorzędny aplikacji. OnSecondaryColor: Kolor tekstu na tle SecondaryColor. BackgroundColor: Kolor tła aplikacji. OnBackgroundColor: Kolor tekstu na tle BackgroundColor. SurfaceColor: Kolor powierzchni aplikacji. OnSurfaceColor: Kolor tekstu na tle SurfaceColor. ErrorColor: Kolor błędu aplikacji. OnErrorColor: Kolor tekstu na tle ErrorColor. BorderType: Typ obramowania aplikacji. Host_Logo: Logo hosta aplikacji.

  • Ustawia kolor tła dla interfejsu użytkownika DrivetrainSetupUIFigure.
app.DrivetrainSetupUIFigure.Color = BackgroundColor;
  • Ustawia kolor czcionki dla etykiety Copyright2021BalticRacingbyEricDorniedenLabel.
app.Copyright2021BalticRacingbyEricDorniedenLabel.FontColor = OnBackgroundColor;
  • Ustawia kolor czcionki, tła i typ obramowania dla panelu PowertrainDataPanel.
app.PowertrainDataPanel.ForegroundColor = OnBackgroundColor;
app.PowertrainDataPanel.BackgroundColor = BackgroundColor;
app.PowertrainDataPanel.BorderType = BorderType;
  • Ustawia kolor czcionki, tła i typ obramowania dla panelu loadPanel.
app.loadPanel.ForegroundColor = OnSurfaceColor;
app.loadPanel.BackgroundColor = SurfaceColor;
app.loadPanel.BorderType = BorderType;
  • Ustawia kolor czcionki, tła i typ obramowania dla panelu Panel.
app.Panel.ForegroundColor = OnSurfaceColor;
app.Panel.BackgroundColor = SurfaceColor;
app.Panel.BorderType = BorderType;
  • Ustawia kolor czcionki, tła i typ obramowania dla panelu EPowertrainParametersPanel.
app.EPowertrainParametersPanel.ForegroundColor = OnSurfaceColor;
app.EPowertrainParametersPanel.BackgroundColor = SurfaceColor;
app.EPowertrainParametersPanel.BorderType = BorderType;
  • Ustawia kolor czcionki, tła i typ obramowania dla panelu ChaindrivePanel.
app.ChaindrivePanel.ForegroundColor = OnSurfaceColor;
app.ChaindrivePanel.BackgroundColor = SurfaceColor;
app.ChaindrivePanel.BorderType = BorderType;
  • Ustawia kolor czcionki, tła i typ obramowania dla panelu GearboxPanel.
app.GearboxPanel.ForegroundColor = OnSurfaceColor;
app.GearboxPanel.BackgroundColor = SurfaceColor;
app.GearboxPanel.BorderType = BorderType;
  • Ustawia kolor czcionki dla przycisku PowertrainSwitch.
app.PowertrainSwitch.FontColor = OnSurfaceColor;
  • Ustawia kolor czcionki dla etykiety LayoutDropDownLabel oraz kolor tła i czcionki dla rozwijanej listy LayoutDropDown.
app.LayoutDropDownLabel.FontColor = OnSurfaceColor;
app.LayoutDropDown.BackgroundColor = PrimaryColor;
app.LayoutDropDown.FontColor = OnPrimaryColor;

Analogicznie są ustawiane inne kolory.

  • Funkcja saveData zapisuje dane z aplikacji do obiektu CallingApp. app - Obiekt aplikacji zawierający dane do zapisania.
function saveData(app)
  • Zapisuje dane z rozwijanej listy EnginePresetDropDown do obiektu CallingApp.engineData
app.CallingApp.engineData = app.EnginePresetDropDown.Items;
  • Zapisuje wartość z pola PowerlimitWEditField do obiektu CallingApp.p_max
app.CallingApp.p_max = app.PowerlimitWEditField.Value;
  • Zapisuje wartość z pola DrivetrainEfficencyEditField do obiektu CallingApp.drivetrain_eff
app.CallingApp.drivetrain_eff = app.DrivetrainEfficencyEditField.Value;

Analogicznie są zapisywane inne wartości.

  • Sprawdza, który układ silnika jest wybrany i dostosowuje liczbę silników w obiekcie CallingApp.num_motors
var Motorsdropdown = app.LayoutDropDown.Value;
  • Wybiera odpowiednią liczbę silników na podstawie wartości wybranej z rozwijanej listy. Motorsdropdown - wartość wybrana z rozwijanej listy
if (Motorsdropdown == "2 Motor RWD") {
    app.CallingApp.num_motors = 2;
} else if (Motorsdropdown == "1 Motor RWD") {
    app.CallingApp.num_motors = 1;
} else if (Motorsdropdown == "AWD") {
    app.CallingApp.num_motors = 4;
}
  • Ustawienie elementów rozwijanej listy EnginePresetDropDown na wartości z app.CallingApp.engineData
app.EnginePresetDropDown.Items = app.CallingApp.engineData;
  • Ustawienie wartości pola PowerlimitWEditField na app.CallingApp.p_max
app.PowerlimitWEditField.Value = app.CallingApp.p_max;
  • Ustawienie wartości pola DrivetrainEfficencyEditField na app.CallingApp.drivetrain_eff
app.DrivetrainEfficencyEditField.Value = app.CallingApp.drivetrain_eff;
  • Ustawienie wartości pola TorquemultiplierEditField na app.CallingApp.trq_multiplier
app.TorquemultiplierEditField.Value = app.CallingApp.trq_multiplier;
  • Ustawienie danych tabeli GearboxTable na app.CallingApp.i_param
app.GearboxTable.Data = app.CallingApp.i_param;
  • Ustawienie wartości pola InverterEfficiencyEditField na app.CallingApp.invertor_eff
app.InverterEfficiencyEditField.Value = app.CallingApp.invertor_eff;
  • Ustawienie wartości pola EnableGearboxCheckBox na app.CallingApp.gearbox
app.EnableGearboxCheckBox.Value = app.CallingApp.gearbox;

Analogicznie są ustawiane inne pola wartości.

  • Ustawienie tekstu rozwijanej listy EngineLayoutDropDown w zależności od wartości app.CallingApp.num_motors
if (app.CallingApp.num_motors == 1) {
    app.LayoutDropDown.Value = "1 Motor RWD";
} else if (app.CallingApp.num_motors == 2) {
    app.LayoutDropDown.Value = "2 Motor RWD";
} else if (app.CallingApp.num_motors == 4) {
    app.LayoutDropDown.Value = "AWD";
}
  • Aktywacja/dezaktywacja parametrów E/C Panelu w zależności od wartości pola PowertrainSwitch
if (app.PowertrainSwitch.Value == "Electric") {
    app.PowerlimitWEditField.Enable = true;
    app.InverterEfficiencyEditField.Enable = true;
} else {
    app.PowerlimitWEditField.Enable = false;
    app.InverterEfficiencyEditField.Enable = false;
}
  • Dla każdego wiersza w tabeli, funkcja wywołuje funkcję updateGearRatio(app) w celu obliczenia całkowitego przełożenia. Następnie funkcja aktualizuje wartości w drugiej i trzeciej kolumnie tabeli na podstawie obliczonych wartości.
for i = 1:size(app.GearboxTable.Data, 1)
    i_tot = updateGearRatio(app);
    
    app.GearboxTable.Data(i,2) = app.GearboxTable.Data(i,1) * i_tot;
    app.GearboxTable.Data(i,3) =  app.n_max1minEditField.Value/(30/pi*app.GearboxTable.Data(i,2)/app.CallingApp.R0)*3.6;
  • Włącza możliwość edycji pól związanych z przesunięciami biegów.
app.t_shiftsEditField.Enable
  • Włącza lub wyłącza możliwość edycji etykiety pola t_shiftsEditField.
app.t_shiftsEditFieldLabel.Enable
  • Włącza lub wyłącza możliwość edycji pola n_shift1minEditField.
app.n_shift1minEditField.Enable

Analogicznie są włączabne możliwości edycji w innych polach.

  • Kod wykonywany po utworzeniu komponentu
function startupFcn(app, mainapp)
  • Aktualizuje wykres momentu i mocy silnika na podstawie danych z UITable
updateMotorGraph(app);
  • Callback edycji komórki: UITable
function UITableCellEdit(app, event)
updateMotorGraph(app);
  • Funkcja wywoływana po zmianie wartości: LayoutDropDown
function LayoutDropDownValueChanged(app, event)
updateMotorGraph(app);
  • Funkcja wywoływana po zmianie wartości: TorquemultiplierEditField
function TorquemultiplierEditFieldValueChanged(app, event)
updateMotorGraph(app);

Analogicznie są wywoływane inne funckje

  • Dodaje wpis do UITable
data = app.UITable.Data;
app.UITable.Data = [data; [0 0]];
  • Funkcja wywoływana po naciśnięciu przycisku Button_2. Usuwa ostatni wpis w tabeli UITable.
    data = app.UITable.Data;
    data((length(data)),:) = [];
    app.UITable.Data = data;
  • Funkcja wywoływana przy próbie zamknięcia okna DrivetrainSetupUIFigure. Zapisuje dane i wyłącza przycisk Drivetrain Options w głównym oknie aplikacji.
function DrivetrainSetupUIFigureCloseRequest(app, event)
    saveData(app);
    app.CallingApp.DrivetrainButton.Enable = 'on';
    delete(app)
  • Funkcja wywoływana po naciśnięciu przycisku SaveButton.
function SaveButtonPushed(app, event)
    saveData(app);
  • Funkcja wywoływana po naciśnięciu przycisku ResetButton.
function ResetButtonPushed(app, event)
    loadData(app);
  • Funkcja wywoływana po zmianie wartości pola InverterEfficiencyEditField. Aktualizuje wykres silnika.
function InverterEfficiencyEditFieldValueChanged(app, event)
    updateMotorGraph(app);
  • Funkcja wywoływana po zmianie wartości przełącznika PowertrainSwitch. Aktualizuje parametry zależne od rodzaju napędu.
function PowertrainSwitchValueChanged(app, event)
    value = app.PowertrainSwitch.Value;
    if value == "Electric"      
        app.PowerlimitWEditField.Enable = true;
        app.InverterEfficiencyEditField.Enable = true;
        app.CallingApp.ptype = 1; 
    else   
        app.PowerlimitWEditField.Enable = false;
        app.InverterEfficiencyEditField.Enable = false;
        app.CallingApp.ptype = 0;      
    end
    updateMotorGraph(app)
    updateGearRatio(app)
  • Funkcja wywoływana po naciśnięciu przycisku Button_3. Dodaje nowy wiersz do tabeli GearboxTable.
function Button_3Pushed(app, event)
    data = app.GearboxTable.Data;
    app.GearboxTable.Data = [data; 0,0,0];
  • Funkcja wywoływana po naciśnięciu przycisku Button_4. Usuwa ostatni wpis w tabeli GearboxTable.
function Button_4Pushed(app, event)
    Deletes the last entry in the UITable
    data = app.GearboxTable.Data;
    data((size(data,1)),:,:) = [];
    app.GearboxTable.Data = data;
  • Funkcja wywoływana po zmianie wartości pola i_PEditField. Aktualizuje wykres silnika.
function i_PEditFieldValueChanged(app, event)
    updateMotorGraph(app);
  • Funkcja wywoływana po naciśnięciu przycisku PlotGearboxdataButton. Wyświetla wykres danych z tabeli GearboxTable.
function PlotGearboxdataButtonPushed(app, event)
    plotGearboxData(app.GearboxTable.Data,app.n_shift1minEditField.Value,app.t_shiftsEditField.Value,app.n_max1minEditField.Value);
  • Funkcja wywoływana po edycji komórki w tabeli GearboxTable. Aktualizuje przekładnie.
function GearboxTableCellEdit(app, event)
    updateGearRatios(app);      
  • Funkcja wywoływana po zmianie wartości pola EnableGearboxCheckBox. Aktualizuje przekładnie.
function EnableGearboxCheckBoxValueChanged(app, event)
    updateGearbox(app);    
  • Funkcja wywoływana po naciśnięciu przycisku TY19BaselineButton. Ustawia wartości związane z układem napędowym dla trybu spalinowego, ładuje dane z pliku “Dynojet Momentenverlauf.mat”, ustawia parametry układu napędowego dla symulacji oraz wywołuje funkcję loadData(app) w celu załadowania danych.
function TY19BaselineButtonPushed(app, event)
    app.PowertrainSwitch.Value = "Combustion";
    app.PowerlimitWEditField.Enable = false;
    app.InverterEfficiencyEditField.Enable = false;
    app.EnableGearboxCheckBox.Value = 1;

    triumphEngine = load('Dynojet Momentenverlauf.mat'); 

ptype - Typ napędu. n_max - Maksymalna prędkość obrotowa. i_param - Parametry prądowe. i_P - Wzmocnienie regulatora prądu. z_chaindrive - Liczba zębów w łańcuchu napędowym. z_sprocket - Liczba zębów w zębatce. gearbox - Przełożenie skrzyni biegów. engine_param - Parametry silnika. num_motors - Liczba silników. idleRPM - Prędkość obrotowa na biegu jałowym.

    app.CallingApp.ptype = 0; 
    app.CallingApp.n_max = 11000;
    app.CallingApp.i_param = [1.857; 1.565; 1.35; 1.238; 1.136];
    app.CallingApp.i_P = 1.848;
    app.CallingApp.z_chaindrive = 37;
    app.CallingApp.z_sprocket = 11;  
    app.CallingApp.gearbox = 1;
    app.CallingApp.engine_param = [triumphEngine.n(:) triumphEngine.M(:)];
    app.CallingApp.num_motors = 1;
    app.CallingApp.idleRPM = 2000;
    loadData(app);
end
  • Funkcja wywoływana po naciśnięciu przycisku ElectricBaselineButton, ustawia wartości związane z układem napędowym dla trybu elektrycznego, umożliwia edycję pól PowerlimitWEditField i InverterEfficiencyEditField, wyłącza pole EnableGearboxCheckBox, ustawia parametry układu napędowego dla symulacji oraz wywołuje funkcję loadData(app) w celu załadowania danych.
function ElectricBaselineButtonPushed(app, event)
    app.PowertrainSwitch.Value = "Electric";
    app.PowerlimitWEditField.Enable = true;
    app.InverterEfficiencyEditField.Enable = true;
    app.EnableGearboxCheckBox.Value = 0;

    app.CallingApp.ptype = 1; 
    app.CallingApp.n_max = 6000;
    app.CallingApp.i_param = 1;
    app.CallingApp.i_P = 1;
    app.CallingApp.z_chaindrive = 66;
    app.CallingApp.z_sprocket = 17;     
    app.CallingApp.gearbox = 0;
    app.CallingApp.engine_param = [0 140; 1000 140; 2000 138; 3000 136; 4000 135; 5000 127; 6000 115];
    app.CallingApp.num_motors = 2;
    app.CallingApp.idleRPM = 0;

    loadData(app);
end
  • Funkcja wywoływana po naciśnięciu przycisku TY20BaselineButton, ustawia wartości związane z układem napędowym dla trybu spalania, ładuje dane z pliku “Dynojet Momentenverlauf.mat”, Ustawia parametry układu napędowego dla symulacji oraz wywołuje funkcję loadData(app) w celu załadowania danych.
function TY20BaselineButtonPushed(app, event)
    app.PowertrainSwitch.Value = "Combustion";
    app.PowerlimitWEditField.Enable = false;
    app.InverterEfficiencyEditField.Enable = false;
    app.EnableGearboxCheckBox.Value = 1;

    triumphEngine = load('Dynojet Momentenverlauf.mat'); 

    app.CallingApp.ptype = 0; 
    app.CallingApp.n_max = 11000;
    app.CallingApp.i_param = [2.579; 1.720; 1.429; 1.238];
    app.CallingApp.i_P = 1.848;
    app.CallingApp.z_chaindrive = 37;
    app.CallingApp.z_sprocket = 11;  
    app.CallingApp.gearbox = 1;
    app.CallingApp.engine_param = [triumphEngine.n(:) triumphEngine.M(:)];
    app.CallingApp.num_motors = 1;
    app.CallingApp.idleRPM = 2000;

    loadData(app);
  • Funkcja wywoływana po zmianie wartości pola ChaindriveSingleGearsetCheckBox, ustawia wartość zmiennej i_chain na podstawie wartości pól związanych z przekładnią, jeśli pole ChaindriveSingleGearsetCheckBox jest zaznaczone, włącza pole związane z ilością zębów koła zębatego.
function ChaindriveSingleGearsetCheckBoxValueChanged(app, event)
    value = app.ChaindriveSingleGearsetCheckBox.Value;

    if value
        app.i_chain = app.z_sprocketEditField.Value * app.z_chaindriveEditField.Value;
        app.z_sprocketEditField.Enable =  'true';
    else
        app.i_chain = 1;
  • Funkcja wywoływana po zmianie wartości w polu EnginePresetDropDown, aktualizuje parametry silnika na podstawie wybranego silnika oraz Aktualizuje interfejs użytkownika.
function EnginePresetDropDownValueChanged(app, event)
    value = app.EnginePresetDropDown.Value;
  • Wczytaj plik .mat dla wybranego silnika
engine = load([value '.mat']); 
  • Wczytaj parametry silnika z pliku .mat
app.CallingApp.engine_param = [engine.n(:) engine.M(:)];
  • Funkcja wywoływana po naciśnięciu przycisku SaveEngineButton, zapisuje zmienne silnika do pliku .mat oraz dodaje nowy silnik do listy rozwijanej, jeśli nazwa nie jest już częścią listy.
function SaveEngineButtonPushed(app, event)
    data = app.UITable.Data;     
    n = data(:,1);
    M = data(:,2);
  • Otwiera okno dialogowe do zapisu pliku
    [filename, pathname] = uiputfile('*.mat','Zapisz zmienne silnika jako','NowySilnik.mat');
    newfilename = fullfile(pathname, filename);
  • Zapisuje plik z podanymi parametrami
    save(newfilename, 'n','M');
  • Dodaje nowy silnik do listy rozwijanej, jeśli nazwa nie jest już częścią listy.
    if ~strcmp(app.EnginePresetDropDown.Items, filename(1:end-4))
    data = app.EnginePresetDropDown.Items;
    data(end) = [];
    app.EnginePresetDropDown.Items = [data filename(1:end-4) "NowySilnik"];
    app.CallingApp.engineData = app.EnginePresetDropDown.Items;
  • Funkcja wywoływana po naciśnięciu przycisku DeleteEngineButton, usuwa wybrany silnik z listy rozwijanej oraz aktualizuje interfejs użytkownika.
function DeleteEngineButtonPushed(app, event)
    selected = app.EnginePresetDropDown.Value;
  • Sprawdza, czy użytkownik próbuje usunąć wpis “NowySilnik”
    if selected == "NowySilnik"
    app.CallingApp.engine_param = [0 0; 1000 0; 2000 0; 3000 0; 4000 0; 5000 0; 6000 0];
    return;
end
    data = app.EnginePresetDropDown.Items;
  • Znajduje indeks wybranego silnika i usuwa go z listy
    ind = find(strcmp(data,selected));
    data(ind) = [];
  • Aktualizuj listę rozwijaną
    app.EnginePresetDropDown.Items = data;
    app.CallingApp.engineData = data;
  • Przełącza na pierwszy silnik
    app.EnginePresetDropDown.Value = app.EnginePresetDropDown.Items(1);
  • Tworzenie UIFigure i komponentów
function createComponents(app)
  • Ustawia widoczność figury na wyłączoną.
app.DrivetrainSetupUIFigure = uifigure('Visible', 'off');
  • Ustawia pozycję figury na [100 100 1107 764].
app.DrivetrainSetupUIFigure.Position = [100 100 1107 764];
  • Ustawia nazwę figury na ‘Drivetrain Setup’.
app.DrivetrainSetupUIFigure.Name = 'Drivetrain Setup';
  • Ustawia ikonę figury na ‘Baltic.png’.
app.DrivetrainSetupUIFigure.Icon = 'Baltic.png';
  • Wyłącza możliwość zmiany rozmiaru figury.
app.DrivetrainSetupUIFigure.Resize = 'off';
  • Ustawia funkcję wywoływaną przy próbie zamknięcia figury na DrivetrainSetupUIFigureCloseRequest.
app.DrivetrainSetupUIFigure.CloseRequestFcn = createCallbackFcn(app, @DrivetrainSetupUIFigureCloseRequest, true);
  • Tworzenie panelu PowertrainDataPanel
app.PowertrainDataPanel = uipanel(app.DrivetrainSetupUIFigure);
app.PowertrainDataPanel.Title = 'Dane napędu';
app.PowertrainDataPanel.Position = [2 1 1107 764];
  • Tworzenie UIAxes
app.UIAxes = uiaxes(app.PowertrainDataPanel);
title(app.UIAxes, 'Pojedynczy silnik')
xlabel(app.UIAxes, 'RPM [1/min]')
ylabel(app.UIAxes, 'Moment obrotowy [Nm]')
app.UIAxes.XTickLabelRotation = 0;
app.UIAxes.YTickLabelRotation = 0;
app.UIAxes.ZTickLabelRotation = 0;
app.UIAxes.Position = [552 535 525 185];
  • Tworzenie UIAxes2
app.UIAxes2 = uiaxes(app.PowertrainDataPanel);
title(app.UIAxes2, 'Tytuł')
xlabel(app.UIAxes2, 'X')
ylabel(app.UIAxes2, 'Y')
app.UIAxes2.XTickLabelRotation = 0;
app.UIAxes2.YTickLabelRotation = 0;
app.UIAxes2.ZTickLabelRotation = 0;
app.UIAxes2.Position = [552 130 525 185];
  • Tworzenie UIAxes3
app.UIAxes3 = uiaxes(app.PowertrainDataPanel);
title(app.UIAxes3, 'Tytuł')
xlabel(app.UIAxes3, 'X')
ylabel(app.UIAxes3, 'Y')
app.UIAxes3.XTickLabelRotation = 0;
app.UIAxes3.YTickLabelRotation = 0;
app.UIAxes3.ZTickLabelRotation = 0;
app.UIAxes3.Position = [552 333 525 185];
  • Tworzenie panelu GearboxPanel
app.GearboxPanel = uipanel(app.PowertrainDataPanel);
app.GearboxPanel.TitlePosition = 'centertop';
app.GearboxPanel.Title = 'Skrzynia biegów';
app.GearboxPanel.Position = [263 83 257 480];
  • Tworzenie etykiety t_shiftsEditFieldLabel
app.t_shiftsEditFieldLabel = uilabel(app.GearboxPanel);
app.t_shiftsEditFieldLabel.HorizontalAlignment = 'right';
app.t_shiftsEditFieldLabel.Position = [77 398 55 23];
app.t_shiftsEditFieldLabel.Text = 't_shift [s]';
  • Tworzenie pola edycyjnego t_shiftsEditField
app.t_shiftsEditField = uieditfield(app.GearboxPanel, 'numeric');
app.t_shiftsEditField.LowerLimitInclusive = 'off';
app.t_shiftsEditField.UpperLimitInclusive = 'off';
app.t_shiftsEditField.Limits = [0 Inf];
app.t_shiftsEditField.Position = [150 399 87 22];
app.t_shiftsEditField.Value = 0.035;
  • Tworzenie etykiety n_shift1minEditFieldLabel
app.n_shift1minEditFieldLabel = uilabel(app.GearboxPanel);
app.n_shift1minEditFieldLabel.HorizontalAlignment = 'right';
app.n_shift1minEditFieldLabel.Position = [51 371 80 23];
app.n_shift1minEditFieldLabel.Text = 'n_shift [1/min]';
  • Tworzenie pola edycyjnego n_shift1minEditField
app.n_shift1minEditField = uieditfield(app.GearboxPanel, 'numeric');
app.n_shift1minEditField.UpperLimitInclusive = 'off';
app.n_shift1minEditField.Limits = [1 Inf];
app.n_shift1minEditField.ValueDisplayFormat = '%.0f';
app.n_shift1minEditField.Tooltip = {''};
app.n_shift1minEditField.Position = [150 372 87 22];
app.n_shift1minEditField.Value = 10500;
  • Tworzenie przycisku Button_3
app.Button_3 = uibutton(app.GearboxPanel, 'push');
app.Button_3.ButtonPushedFcn = createCallbackFcn(app, @Button_3Pushed, true);
app.Button_3.Position = [10 26 37 22];
app.Button_3.Text = '+';
  • Tworzenie przycisku Button_4
app.Button_4 = uibutton(app.GearboxPanel, 'push');
app.Button_4.ButtonPushedFcn = createCallbackFcn(app, @Button_4Pushed, true);
app.Button_4.Position = [47 26 37 22];
app.Button_4.Text = '-';
  • Tworzenie tabeli GearboxTable
app.GearboxTable = uitable(app.GearboxPanel);
app.GearboxTable.ColumnName = {'Gear Ratio'; 'Final Ratio'; 'Vmax [km/h]'};
app.GearboxTable.RowName = {};
app.GearboxTable.ColumnEditable = [true false false];
app.GearboxTable.CellEditCallback = createCallbackFcn(app, @GearboxTableCellEdit, true);
app.GearboxTable.Position = [7 47 245 282];
  • Tworzenie przycisku PlotGearboxdataButton
app.PlotGearboxdataButton = uibutton(app.GearboxPanel, 'push');
app.PlotGearboxdataButton.ButtonPushedFcn = createCallbackFcn(app, @PlotGearboxdataButtonPushed, true);
app.PlotGearboxdataButton.Position = [136 14 112 22];
app.PlotGearboxdataButton.Text = 'Plot Gearbox data';
  • Tworzenie pola wyboru EnableGearboxCheckBox
app.EnableGearboxCheckBox = uicheckbox(app.GearboxPanel);
app.EnableGearboxCheckBox.ValueChangedFcn = createCallbackFcn(app, @EnableGearboxCheckBoxValueChanged, true);
app.EnableGearboxCheckBox.Text = 'Enable Gearbox';
app.EnableGearboxCheckBox.Position = [7 435 109 22];
  • Tworzenie etykiety n_downshift1minEditFieldLabel
app.n_downshift1minEditFieldLabel = uilabel(app.GearboxPanel);
app.n_downshift1minEditFieldLabel.HorizontalAlignment = 'right';
app.n_downshift1minEditFieldLabel.Position = [15 344 116 23];
app.n_downshift1minEditFieldLabel.Text = 'n_downshift [1/min]';
  • Tworzenie pola edycyjnego n_downshift1minEditField
app.n_downshift1minEditField = uieditfield(app.GearboxPanel, 'numeric');
app.n_downshift1minEditField.UpperLimitInclusive = 'off';
app.n_downshift1minEditField.Limits = [1 Inf];
app.n_downshift1minEditField.ValueDisplayFormat = '%.0f';
app.n_downshift1minEditField.Tooltip = {''};
app.n_downshift1minEditField.Position = [150 345 87 22];
app.n_downshift1minEditField.Value = 6000;
  • Tworzenie panelu ChaindrivePanel
app.ChaindrivePanel = uipanel(app.PowertrainDataPanel);
app.ChaindrivePanel.Title = 'Chaindrive';
app.ChaindrivePanel.Position = [264 576 256 162];
  • Tworzenie etykiety i_PLabel
app.i_PLabel = uilabel(app.ChaindrivePanel);
app.i_PLabel.HorizontalAlignment = 'right';
app.i_PLabel.Position = [136 112 55 23];
app.i_PLabel.Text = 'i_P [-]';
  • Tworzenie pola edycyjnego i_PEditField
app.i_PEditField = uieditfield(app.ChaindrivePanel, 'numeric');
app.i_PEditField.LowerLimitInclusive = 'off';
app.i_PEditField.UpperLimitInclusive = 'off';
app.i_PEditField.Limits = [0 Inf];
app.i_PEditField.ValueChangedFcn = createCallbackFcn(app, @i_PEditFieldValueChanged, true);
app.i_PEditField.Position = [200 112 48 22];
app.i_PEditField.Value = 1;
  • Tworzenie panelu loadPanel
app.loadPanel = uipanel(app.PowertrainDataPanel);
app.loadPanel.Title = 'load';
app.loadPanel.Position = [566 42 524 56];
  • Tworzenie przycisku TY19BaselineButton
app.TY19BaselineButton = uibutton(app.loadPanel, 'push');
app.TY19BaselineButton.ButtonPushedFcn = createCallbackFcn(app, @TY19BaselineButtonPushed, true);
app.TY19BaselineButton.Position = [14 8 100 22];
app.TY19BaselineButton.Text = 'TY-19 Baseline';
  • Tworzenie przycisku ElectricBaselineButton
app.ElectricBaselineButton = uibutton(app.loadPanel, 'push');
app.ElectricBaselineButton.ButtonPushedFcn = createCallbackFcn(app, @ElectricBaselineButtonPushed, true);
app.ElectricBaselineButton.Position = [232 8 108 22];
app.ElectricBaselineButton.Text = 'Electric Baseline';
  • Tworzenie przycisku ResetButton
app.ResetButton = uibutton(app.loadPanel, 'push');
app.ResetButton.ButtonPushedFcn = createCallbackFcn(app, @ResetButtonPushed, true);
app.ResetButton.FontSize = 14;
app.ResetButton.Position = [352 6 56 26];
app.ResetButton.Text = 'Reset';
  • Tworzenie przycisku SaveButton
app.SaveButton = uibutton(app.loadPanel, 'push');
app.SaveButton.ButtonPushedFcn = createCallbackFcn(app, @SaveButtonPushed, true);
app.SaveButton.FontSize = 14;
app.SaveButton.Position = [415 6 99 26];
app.SaveButton.Text = 'Save';
  • Tworzenie przycisku TY20BaselineButton
app.TY20BaselineButton = uibutton(app.loadPanel, 'push');
app.TY20BaselineButton.ButtonPushedFcn = createCallbackFcn(app, @TY20BaselineButtonPushed, true);
app.TY20BaselineButton.Position = [123 8 100 22];
app.TY20BaselineButton.Text = 'TY-20 Baseline';
  • Tworzenie panelu Panel_2
app.Panel_2 = uipanel(app.PowertrainDataPanel);
app.Panel_2.Position = [264 575 256 107];
  • Tworzenie CheckBoxa dla napędu łańcuchowego / pojedynczego układu biegów
app.ChaindriveSingleGearsetCheckBox = uicheckbox(app.Panel_2);
app.ChaindriveSingleGearsetCheckBox.ValueChangedFcn = createCallbackFcn(app, @ChaindriveSingleGearsetCheckBoxValueChanged, true);
app.ChaindriveSingleGearsetCheckBox.Text = {'Napęd łańcuchowy /'; 'Pojedynczy układ biegów'};
app.ChaindriveSingleGearsetCheckBox.Position = [6 74 101 28];
  • Tworzenie etykiety dla pola edycji zębów koła zębatego
app.z_sprocketEditFieldLabel = uilabel(app.Panel_2);
app.z_sprocketEditFieldLabel.HorizontalAlignment = 'right';
app.z_sprocketEditFieldLabel.Position = [112 77 78 22];
app.z_sprocketEditFieldLabel.Text = 'z_sprocket [-]';
  • Tworzenie pola edycji zębów koła zębatego
app.z_sprocketEditField = uieditfield(app.Panel_2, 'numeric');
app.z_sprocketEditField.UpperLimitInclusive = 'off';
app.z_sprocketEditField.Limits = [1 Inf];
app.z_sprocketEditField.ValueChangedFcn = createCallbackFcn(app, @z_sprocketEditFieldValueChanged, true);
app.z_sprocketEditField.Position = [198 77 49 22];
app.z_sprocketEditField.Value = 17;
  • Tworzenie etykiety dla pola edycji zębów napędu łańcuchowego
app.z_chaindriveEditFieldLabel = uilabel(app.Panel_2);
app.z_chaindriveEditFieldLabel.HorizontalAlignment = 'right';
app.z_chaindriveEditFieldLabel.Position = [103 43 87 22];
app.z_chaindriveEditFieldLabel.Text = 'z_chaindrive [-]';
  • Tworzenie pola edycji zębów napędu łańcuchowego
app.z_chaindriveEditField = uieditfield(app.Panel_2, 'numeric');
app.z_chaindriveEditField.UpperLimitInclusive = 'off';
app.z_chaindriveEditField.Limits = [1 Inf];
app.z_chaindriveEditField.ValueChangedFcn = createCallbackFcn(app, @z_chaindriveEditFieldValueChanged, true);
app.z_chaindriveEditField.Position = [198 43 49 22];
app.z_chaindriveEditField.Value = 66;
  • Tworzenie etykiety dla współczynnika przekładni
app.GearRatioLabel = uilabel(app.Panel_2);
app.GearRatioLabel.Position = [159 8 89 22];
app.GearRatioLabel.Text = 'Gear Ratio';
  • Tworzenie etykiety dla rozwijanej listy wyboru silnika
app.EnginePresetDropDownLabel = uilabel(app.PowertrainDataPanel);
app.EnginePresetDropDownLabel.HorizontalAlignment = 'right';
app.EnginePresetDropDownLabel.Position = [21 378 81 22];
app.EnginePresetDropDownLabel.Text = 'Engine Preset';
  • Tworzenie rozwijanej listy wyboru silnika
app.EnginePresetDropDown = uidropdown(app.PowertrainDataPanel);
app.EnginePresetDropDown.Items = {'Triumph_D67LD', 'EMRAX_188_TorqueData_Peak', 'EMRAX_208_TorqueData_Peak', 'Emrax 228', 'Emrax 268', 'Emrax 348', 'Rotax_125_Junior_MAX_evo', 'Rotax_125_MAX_DD2_evo', 'Rotax_125_MAX_evo', 'new Engine'};
app.EnginePresetDropDown.ValueChangedFcn = createCallbackFcn(app, @EnginePresetDropDownValueChanged, true);
app.EnginePresetDropDown.Position = [112 378 135 22];
app.EnginePresetDropDown.Value = 'Triumph_D67LD';
  • Tworzenie przycisku do usuwania silnika
app.DeleteEngineButton = uibutton(app.PowertrainDataPanel, 'push');
app.DeleteEngineButton.ButtonPushedFcn = createCallbackFcn(app, @DeleteEngineButtonPushed, true);
app.DeleteEngineButton.Tooltip = {'Usuwa aktualnie wybrany silnik, jeśli pozostało więcej niż jeden typ silnika.'};
app.DeleteEngineButton.Position = [155 97 91 22];
app.DeleteEngineButton.Text = 'Delete Engine';
  • Tworzenie przycisku do zapisywania silnika
app.SaveEngineButton = uibutton(app.PowertrainDataPanel, 'push');
app.SaveEngineButton.ButtonPushedFcn = createCallbackFcn(app, @SaveEngineButtonPushed, true);
app.SaveEngineButton.Position = [68 97 84 22];
app.SaveEngineButton.Text = 'Save Engine';
  • Tworzenie panelu dla parametrów napędu elektrycznego
app.EPowertrainParametersPanel = uipanel(app.PowertrainDataPanel);
app.EPowertrainParametersPanel.TitlePosition = 'centertop';
app.EPowertrainParametersPanel.Title = 'E Powertrain Parameters';
app.EPowertrainParametersPanel.Position = [18 411 230 92];
  • Tworzenie etykiety dla pola edycji limitu mocy
app.PowerlimitWEditFieldLabel = uilabel(app.EPowertrainParametersPanel);
app.PowerlimitWEditFieldLabel.HorizontalAlignment = 'right';
app.PowerlimitWEditFieldLabel.Position = [33 43 86 22];
app.PowerlimitWEditFieldLabel.Text = 'Power limit [W]';
  • Tworzenie pola edycji limitu mocy
app.PowerlimitWEditField = uieditfield(app.EPowertrainParametersPanel, 'numeric');
app.PowerlimitWEditField.LowerLimitInclusive = 'off';
app.PowerlimitWEditField.UpperLimitInclusive = 'off';
app.PowerlimitWEditField.Limits = [0 Inf];
app.PowerlimitWEditField.ValueDisplayFormat = '%.0f';
app.PowerlimitWEditField.Position = [136 43 87 22];
app.PowerlimitWEditField.Value = 80000;
  • Tworzenie etykiety dla pola edycji sprawności falownika
app.InverterEfficiencyEditFieldLabel = uilabel(app.EPowertrainParametersPanel);
app.InverterEfficiencyEditFieldLabel.HorizontalAlignment = 'right';
app.InverterEfficiencyEditFieldLabel.Position = [1 12 116 22];
app.InverterEfficiencyEditFieldLabel.Text = 'Inverter Efficiency [-]';
  • Tworzenie pola edycji sprawności falownika
app.InverterEfficiencyEditField = uieditfield(app.EPowertrainParametersPanel, 'numeric');
app.InverterEfficiencyEditField.LowerLimitInclusive = 'off';
app.InverterEfficiencyEditField.UpperLimitInclusive = 'off';
app.InverterEfficiencyEditField.Limits = [0 Inf];
app.InverterEfficiencyEditField.ValueChangedFcn = createCallbackFcn(app, @InverterEfficiencyEditFieldValueChanged, true);
app.InverterEfficiencyEditField.Position = [137 12 86 22];
app.InverterEfficiencyEditField.Value = 0.95;
  • Tworzenie panelu
app.Panel = uipanel(app.PowertrainDataPanel);
app.Panel.Title = 'Panel';
app.Panel.Position = [17 517 227 220];
  • Tworzenie przełącznika dla wyboru napędu
app.PowertrainSwitch = uiswitch(app.Panel, 'slider');
app.PowertrainSwitch.Items = {'Electric', 'Combustion'};
app.PowertrainSwitch.ValueChangedFcn = createCallbackFcn(app, @PowertrainSwitchValueChanged, true);
app.PowertrainSwitch.Position = [85 170 45 20];
app.PowertrainSwitch.Value = 'Electric';
  • Tworzenie etykiety dla rozwijanej listy wyboru układu
app.LayoutDropDownLabel = uilabel(app.Panel);
app.LayoutDropDownLabel.HorizontalAlignment = 'right';
app.LayoutDropDownLabel.Position = [40 132 42 22];
app.LayoutDropDownLabel.Text = 'Layout';
  • Tworzenie rozwijanej listy rozmieszczenia napędu.
app.LayoutDropDown = uidropdown(app.Panel);
app.LayoutDropDown.Items = {'2 Motor RWD', '1 Motor RWD', 'AWD'};
app.LayoutDropDown.ValueChangedFcn = createCallbackFcn(app, @LayoutDropDownValueChanged, true);
app.LayoutDropDown.Position = [93 132 107 22];
app.LayoutDropDown.Value = '2 Motor RWD';
  • Tworzenie etykiety pola edycji dla sprawności układu napędowego.
app.DrivetrainEfficencyEditFieldLabel = uilabel(app.Panel);
app.DrivetrainEfficencyEditFieldLabel.HorizontalAlignment = 'right';
app.DrivetrainEfficencyEditFieldLabel.Position = [22 98 123 22];
app.DrivetrainEfficencyEditFieldLabel.Text = 'Sprawność układu napędowego [-]';
  • Tworzenie pola edycji dla sprawności układu napędowego.
app.DrivetrainEfficencyEditField = uieditfield(app.Panel, 'numeric');
app.DrivetrainEfficencyEditField.LowerLimitInclusive = 'off';
app.DrivetrainEfficencyEditField.Limits = [0 1];
app.DrivetrainEfficencyEditField.ValueChangedFcn = createCallbackFcn(app, @DrivetrainEfficencyEditFieldValueChanged, true);
app.DrivetrainEfficencyEditField.Position = [155 98 52 22];
app.DrivetrainEfficencyEditField.Value = 0.95;
  • Tworzenie etykiety pola edycji dla maksymalnej prędkości obrotowej.
app.n_max1minEditFieldLabel = uilabel(app.Panel);
app.n_max1minEditFieldLabel.HorizontalAlignment = 'right';
app.n_max1minEditFieldLabel.Position = [51 68 81 22];
app.n_max1minEditFieldLabel.Text = 'n_max [1/min]';
  • Tworzenie pola edycji dla maksymalnej prędkości obrotowej.
app.n_max1minEditField = uieditfield(app.Panel, 'numeric');
app.n_max1minEditField.UpperLimitInclusive = 'off';
app.n_max1minEditField.Limits = [1 Inf];
app.n_max1minEditField.ValueDisplayFormat = '%.0f';
app.n_max1minEditField.Position = [155 68 53 22];
app.n_max1minEditField.Value = 6000;
  • Tworzenie etykiety pola edycji dla mnożnika momentu obrotowego.
app.TorquemultiplierEditFieldLabel = uilabel(app.Panel);
app.TorquemultiplierEditFieldLabel.HorizontalAlignment = 'right';
app.TorquemultiplierEditFieldLabel.Position = [20 38 108 22];
app.TorquemultiplierEditFieldLabel.Text = 'Mnożnik momentu obrotowego [-]';
  • Tworzenie pola edycji dla mnożnika momentu obrotowego.
app.TorquemultiplierEditField = uieditfield(app.Panel, 'numeric');
app.TorquemultiplierEditField.LowerLimitInclusive = 'off';
app.TorquemultiplierEditField.UpperLimitInclusive = 'off';
app.TorquemultiplierEditField.Limits = [0 Inf];
app.TorquemultiplierEditField.ValueChangedFcn = createCallbackFcn(app, @TorquemultiplierEditFieldValueChanged, true);
app.TorquemultiplierEditField.Position = [155 38 54 22];
app.TorquemultiplierEditField.Value = 1;
  • Tworzenie etykiety pola edycji dla prędkości jałowej.
app.idle_rpm1minEditFieldLabel = uilabel(app.Panel);
app.idle_rpm1minEditFieldLabel.HorizontalAlignment = 'right';
app.idle_rpm1minEditFieldLabel.Position = [42 8 91 22];
app.idle_rpm1minEditFieldLabel.Text = 'Prędkość jałowa [1/min]';
  • Tworzenie pola edycji dla prędkości jałowej.
app.idle_rpm1minEditField = uieditfield(app.Panel, 'numeric');
app.idle_rpm1minEditField.UpperLimitInclusive = 'off';
app.idle_rpm1minEditField.Limits = [0 Inf];
app.idle_rpm1minEditField.Position = [156 8 53 22];
app.idle_rpm1minEditField.Value = 2000;
  • Tworzenie etykiety z informacją o prawach autorskich.
app.Copyright2021BalticRacingbyEricDorniedenLabel = uilabel(app.PowertrainDataPanel);
app.Copyright2021BalticRacingbyEricDorniedenLabel.Position = [834 1 274 22];
app.Copyright2021BalticRacingbyEricDorniedenLabel.Text = 'Copyright © 2021 Baltic Racing by Eric Dornieden';
  • Wyświetlanie logo Baltic Racing.
app.Image2 = uiimage(app.PowertrainDataPanel);
app.Image2.Position = [7 6 196 77];
app.Image2.ImageSource = 'balticracing_logo_transparent.png';
  • Tworzenie przycisku dodawania.
app.Button = uibutton(app.PowertrainDataPanel, 'push');
app.Button.ButtonPushedFcn = createCallbackFcn(app, @ButtonPushed, true);
app.Button.Position = [25 98 21 21];
app.Button.Text = '+';
  • Tworzenie przycisku odejmowania.
app.Button_2 = uibutton(app.PowertrainDataPanel, 'push');
app.Button_2.ButtonPushedFcn = createCallbackFcn(app, @Button_2Pushed, true);
app.Button_2.Position = [45 98 20 21];
app.Button_2.Text = '-';
  • Tworzenie tabeli do wyświetlania danych napędu.
app.UITable = uitable(app.PowertrainDataPanel);
app.UITable.ColumnName = {'RPM [1/min]'; 'Moment obrotowy [Nm]'};
app.UITable.RowName = {};
app.UITable.ColumnEditable = true;
app.UITable.CellEditCallback = createCallbackFcn(app, @UITableCellEdit, true);
app.UITable.Position = [24 119 222 258];
  • Wyświetlanie okna po utworzeniu wszystkich komponentów.
app.DrivetrainSetupUIFigure.Visible = 'on';
  • Konstruktor aplikacji, tworzy obiekt aplikacji Drivetrain, przyjmuje opcjonalne argumenty wejściowe
function app = Drivetrain(varargin)
  • Tworzenie UIFigure i komponentów
createComponents(app)
  • Rejestrowanie aplikacji w App Designer
registerApp(app, app.DrivetrainSetupUIFigure)
  • Wykonanie funkcji startupFcn
runStartupFcn(app, @(app)startupFcn(app, varargin{:}))
  • Jeśli nie ma argumentów wyjściowych, usuń obiekt aplikacji
if nargout == 0
    clear app
  • Usunięcie UIFigure przy usuwaniu aplikacji
delete(app.DrivetrainSetupUIFigure)

2.7 - Linia Krzywa 2D

Funkcja LineCurvature2D oblicza krzywiznę linii 2D. Najpierw dopasowuje wielokąty do punktów, a następnie oblicza krzywiznę analityczną na podstawie wielokątów.

Zmienne wejściowe:

1. Vertices:

  • Macierz M x 2
  • Opis: Lista punktów tworzących linię, gdzie każda z M wierszy zawiera współrzędne x i y danego punktu.
  • Przykład: Vertices = [x1, y1; x2, y2; ...; xM, yM]

2. Lines (opcjonalnie):

  • Macierz N x 2
  • Opis: Lista odcinków linii zdefiniowana przez indeksy punktów z Vertices. Każdy wiersz zawiera dwa indeksy, które definiują odcinek linii.
  • Przykład: Lines = [index1, index2; index2, index3; ...; indexN-1, indexN]
  • Domyślnie: Jeśli Lines nie jest podane, przyjmuje się, że Lines = [1 2; 2 3; ...; M-1 M], co oznacza, że punkty są połączone w kolejności, w jakiej są podane.

Zmienna wyjściowa:

1. k:

  • Wektor M x 1
  • Opis: Wartości krzywizny dla każdego z M punktów linii. Każdy element wektora k odpowiada krzywiźnie w odpowiednim punkcie Vertices.
  • Przykład: k = [k1; k2; ...; kM], gdzie ki to krzywizna w punkcie i.

Przykład użycia:

Jeśli mamy punkty linii:

Vertices = [0, 0; 1, 1; 2, 0; 3, -1]; i chcemy obliczyć krzywiznę, możemy wywołać funkcję: k = LineCurvature2D(Vertices);

Jeśli chcemy określić własne odcinki linii:

Lines = [1, 2; 2, 3; 3, 4];
k = LineCurvature2D(Vertices, Lines);

Przykłady:

Koło

1. Generowanie losowych kątów:

r = sort(rand(15,1)) * 2 * pi;

  • Generujemy 15 losowych liczb w zakresie od 0 do 1 (rand(15,1)).
  • Sortujemy te liczby rosnąco (sort).
  • Przekształcamy je na kąty w zakresie od 0 do 2π poprzez mnożenie przez 2π.

2. Tworzenie punktów okręgu:

Vertices = [sin(r) cos(r)] * 10;

  • Używamy funkcji trygonometrycznych sin i cos, aby przekształcić kąty na współrzędne punktów na okręgu.
  • Skalujemy współrzędne przez 10, aby uzyskać punkty na okręgu o promieniu 10.
  • Vertices to macierz 15x2, gdzie każda para [sin(r_i) cos(r_i)] * 10 reprezentuje współrzędne punktu.

3. Tworzenie linii:

Lines = [(1:size(Vertices,1))' (2:size(Vertices,1)+1']; Lines(end,2) = 1;

  • Tworzymy macierz Lines, która definiuje odcinki linii przez indeksy punktów w Vertices.
  • Każdy wiersz Lines łączy punkt i z punktem i+1.
  • Ostatnia para jest specjalnie ustawiona (Lines(end,2) = 1), aby zamknąć okrąg, łącząc ostatni punkt z pierwszym.

4. Obliczenie krzywizny:

k = LineCurvature2D(Vertices, Lines);

  • Wywołujemy funkcję LineCurvature2D z punktami Vertices i liniami Lines, aby obliczyć krzywiznę.
  • k to wektor wartości krzywizny dla każdego punktu.

figure, hold on;

  • Tworzy nowe okno wykresu.
  • Włącza tryb hold on, co pozwala na nałożenie wielu wykresów na jednej figurze bez ich nadpisywania.

5. Obliczenie normalnych do linii:

N = LineNormals2D(Vertices,Lines);

  • Wywołuje funkcję LineNormals2D, która oblicza normalne do linii w punktach Vertices na podstawie Lines.
  • N to macierz zawierająca wektory normalne dla każdego punktu.

6. Skalowanie wartości krzywizny:

k = k * 100;

  • Skaluje wartości krzywizny k przez mnożenie przez 100, aby lepiej widoczne były na wykresie.
  • N to macierz zawierająca wektory normalne dla każdego punktu.

7. Wykreślanie normalnych do linii:

plot([Vertices(:,1) Vertices(:,1)+k.*N(:,1)]',[Vertices(:,2) Vertices(:,2)+k.*N(:,2)]','g');

  • Wykreśla wektory normalne w każdym punkcie Vertices.
  • Vertices(:,1) to współrzędne x punktów początkowych.
  • Vertices(:,1) + k.*N(:,1) to współrzędne x końców wektorów normalnych.
  • Vertices(:,2) to współrzędne y punktów początkowych.
  • Vertices(:,2) + k.*N(:,2) to współrzędne y końców wektorów normalnych.
  • Kolor wykresu: zielony ('g').

8. Wykreślanie linii:

plot([Vertices(Lines(:,1),1) Vertices(Lines(:,2),1)]',[Vertices(Lines(:,1),2) Vertices(Lines(:,2),2)]','b');

  • Wykreśla linie łączące punkty z Vertices zgodnie z Lines.

  • Vertices(Lines(:,1),1) i Vertices(Lines(:,2),1) to współrzędne x punktów początkowych i końcowych odcinków linii.

  • Vertices(Lines(:,1),2) i Vertices(Lines(:,2),2) to współrzędne y punktów początkowych i końcowych odcinków linii.

  • Kolor wykresu: niebieski ('b').

9. Wykreślanie idealnego okręgu:

plot(sin(0:0.01:2*pi)*10, cos(0:0.01:2*pi)*10, 'r.');

  • Wykreśla idealny okrąg o promieniu 10.

  • sin(0:0.01:2*pi)*10 i cos(0:0.01:2*pi)*10 to współrzędne x i y punktów na okręgu.

  • Kolor wykresu: czerwony ('r').

10. Ustawienie równej skali osi:

axis equal;

  • Ustawia równe jednostki na osiach x i y, co sprawia, że okrąg wygląda proporcjonalnie.

Przykład, Ręka:

1. Wczytanie danych z pliku:

load('testdata');

  • Wczytuje dane z pliku testdata.mat, które zawierają zmienne Vertices (współrzędne punktów) i Lines (lista odcinków linii).

2. Obliczenie krzywizny linii:

k = LineCurvature2D(Vertices, Lines);

  • Wywołuje funkcję LineCurvature2D, która oblicza wartości krzywizny dla punktów zdefiniowanych w Vertices i Lines.
  • k to wektor zawierający wartości krzywizny dla każdego punktu.

3. Utworzenie nowej figury i włączenie trybu hold on:

figure, hold on;

  • Tworzy nowe okno wykresu.
  • Włącza tryb hold on, co pozwala na nałożenie wielu wykresów na jednej figurze bez ich nadpisywania.

4. Obliczenie normalnych do linii:

N = LineNormals2D(Vertices, Lines);

  • Wywołuje funkcję LineNormals2D, która oblicza wektory normalne dla punktów z Vertices na podstawie Lines.
  • N to macierz zawierająca wektory normalne dla każdego punktu.

5. Skalowanie wartości krzywizny:

k = k * 100;

  • Skaluje wartości krzywizny k przez mnożenie przez 100, aby lepiej widoczne były na wykresie.

6. Wykreślanie normalnych do linii:

plot([Vertices(:,1) Vertices(:,1) + k .* N(:,1)]', [Vertices(:,2) Vertices(:,2) + k .* N(:,2)]', 'g');

  • Wykreśla wektory normalne w każdym punkcie Vertices.
  • Vertices(:,1) to współrzędne x punktów początkowych.
  • Vertices(:,1) + k .* N(:,1) to współrzędne x końców wektorów normalnych.
  • Vertices(:,2) to współrzędne y punktów początkowych.
  • Vertices(:,2) + k .* N(:,2) to współrzędne y końców wektorów normalnych.
  • Kolor wykresu: zielony ('g').

7. Wykreślanie linii:

plot([Vertices(Lines(:,1),1) Vertices(Lines(:,2),1)]', [Vertices(Lines(:,1),2) Vertices(Lines(:,2),2)]', 'b'); `

  • Wykreśla linie łączące punkty z Vertices zgodnie z Lines.
  • Vertices(Lines(:,1),1) i Vertices(Lines(:,2),1) to współrzędne x punktów początkowych i końcowych odcinków linii.
  • Vertices(Lines(:,1),2) i Vertices(Lines(:,2),2) to współrzędne y punktów początkowych i końcowych odcinków linii.
  • Kolor wykresu: niebieski ('b').

8. Wykreślanie punktów:

plot(Vertices(:,1), Vertices(:,2), 'r.');

  • Wykreśla punkty Vertices.
  • Kolor wykresu: czerwony ('r').

9. Ustawienie równej skali osi:

axis equal;

  • Ustawia równe jednostki na osiach x i y, co zapewnia proporcjonalne wyświetlanie.

10. Lista zmiennych i ich opis:

Vertices:

  • Typ: Macierz M x 2
  • Opis: Współrzędne punktów (wierzchołków) linii.

Lines:

  • Typ: Macierz N x 2
  • Opis: Lista odcinków linii, zdefiniowana przez indeksy punktów w Vertices.

k:

  • Typ: Wektor M x 1
  • Opis: Wartości krzywizny dla punktów Vertices, skalowane przez 100.

N:

  • Typ: Macierz M x 2
  • Opis: Wektory normalne dla punktów z Vertices, obliczone przez LineNormals2D.

Funkcja

Obliczenie krzywizny linii na podstawie zadanych wierzchołków (Vertices) i odcinków linii (Lines). Obejmuje on kroki takie jak uzupełnianie brakujących sąsiadów, przeliczanie wektorów normalnych oraz obliczanie krzywizny na podstawie dopasowania wielomianu do wierzchołków.

Kod:

% Function is written by D.Kroon University of Twente (August 2011)

% If no line-indices, assume a x(1) connected with x(2), x(3) with x(4) ...
if(nargin<2)
    Lines=[(1:(size(Vertices,1)-1))' (2:size(Vertices,1))'];
end

% Get left and right neighbor of each points
Na=zeros(size(Vertices,1),1); Nb=zeros(size(Vertices,1),1);
Na(Lines(:,1))=Lines(:,2); Nb(Lines(:,2))=Lines(:,1);

% Check for end of line points, without a left or right neighbor
checkNa=Na==0; checkNb=Nb==0;
Naa=Na; Nbb=Nb;
Naa(checkNa)=find(checkNa); Nbb(checkNb)=find(checkNb);

% If no left neighbor use two right neighbors, and the same for right... 
Na(checkNa)=Nbb(Nbb(checkNa)); Nb(checkNb)=Naa(Naa(checkNb));

% Correct for sampeling differences
Ta=-sqrt(sum((Vertices-Vertices(Na,:)).^2,2));
Tb=sqrt(sum((Vertices-Vertices(Nb,:)).^2,2)); 

% If no left neighbor use two right neighbors, and the same for right... 
Ta(checkNa)=-Ta(checkNa); Tb(checkNb)=-Tb(checkNb);

% Fit a polygons to the vertices 
% x=a(3)*t^2 + a(2)*t + a(1) 
% y=b(3)*t^2 + b(2)*t + b(1) 
% we know the x,y of every vertice and set t=0 for the vertices, and
% t=Ta for left vertices, and t=Tb for right vertices,  
x = [Vertices(Na,1) Vertices(:,1) Vertices(Nb,1)];
y = [Vertices(Na,2) Vertices(:,2) Vertices(Nb,2)];
M = [ones(size(Tb)) -Ta Ta.^2 ones(size(Tb)) zeros(size(Tb)) zeros(size(Tb)) ones(size(Tb)) -Tb Tb.^2];
invM=inverse3(M);
a(:,1)=invM(:,1,1).*x(:,1)+invM(:,2,1).*x(:,2)+invM(:,3,1).*x(:,3);
a(:,2)=invM(:,1,2).*x(:,1)+invM(:,2,2).*x(:,2)+invM(:,3,2).*x(:,3);
a(:,3)=invM(:,1,3).*x(:,1)+invM(:,2,3).*x(:,2)+invM(:,3,3).*x(:,3);
b(:,1)=invM(:,1,1).*y(:,1)+invM(:,2,1).*y(:,2)+invM(:,3,1).*y(:,3);
b(:,2)=invM(:,1,2).*y(:,1)+invM(:,2,2).*y(:,2)+invM(:,3,2).*y(:,3);
b(:,3)=invM(:,1,3).*y(:,1)+invM(:,2,3).*y(:,2)+invM(:,3,3).*y(:,3);

% Calculate the curvature from the fitted polygon
k = 2*(a(:,2).*b(:,3)-a(:,3).*b(:,2)) ./ ((a(:,2).^2+b(:,2).^2).^(3/2));

function  Minv  = inverse3(M)
% This function does inv(M) , but then for an array of 3x3 matrices
adjM(:,1,1)=  M(:,5).*M(:,9)-M(:,8).*M(:,6);
adjM(:,1,2)=  -(M(:,4).*M(:,9)-M(:,7).*M(:,6));
adjM(:,1,3)=  M(:,4).*M(:,8)-M(:,7).*M(:,5);
adjM(:,2,1)=  -(M(:,2).*M(:,9)-M(:,8).*M(:,3));
adjM(:,2,2)=  M(:,1).*M(:,9)-M(:,7).*M(:,3);
adjM(:,2,3)=  -(M(:,1).*M(:,8)-M(:,7).*M(:,2));
adjM(:,3,1)=  M(:,2).*M(:,6)-M(:,5).*M(:,3);
adjM(:,3,2)=  -(M(:,1).*M(:,6)-M(:,4).*M(:,3));
adjM(:,3,3)=  M(:,1).*M(:,5)-M(:,4).*M(:,2);
detM=M(:,1).*M(:,5).*M(:,9)-M(:,1).*M(:,8).*M(:,6)-M(:,4).*M(:,2).*M(:,9)+M(:,4).*M(:,8).*M(:,3)+M(:,7).*M(:,2).*M(:,6)-M(:,7).*M(:,5).*M(:,3);
Minv=bsxfun(@rdivide,adjM,detM);

Kroki działania:

1. Sprawdzenie i przypisanie domyślnych indeksów linii:

if(nargin<2) Lines=[(1:(size(Vertices,1)-1))' (2:size(Vertices,1))']; end

  • Jeśli nie podano Lines, domyślnie zakłada, że punkty są połączone sekwencyjnie.

2. Znalezienie lewego i prawego sąsiada dla każdego punktu:

Na=zeros(size(Vertices,1),1); Nb=zeros(size(Vertices,1),1); Na(Lines(:,1))=Lines(:,2); Nb(Lines(:,2))=Lines(:,1);

  • Na i Nb przechowują indeksy lewych i prawych sąsiadów dla każdego punktu.

3. Sprawdzenie punktów bez sąsiadów i uzupełnienie braków:

checkNa=Na==0; checkNb=Nb==0;
Naa=Na; Nbb=Nb;
Naa(checkNa)=find(checkNa); Nbb(checkNb)=find(checkNb);

Na(checkNa)=Nbb(Nbb(checkNa)); Nb(checkNb)=Naa(Naa(checkNb));
  • Jeśli punkt nie ma lewego lub prawego sąsiada, używa dwóch sąsiadów z przeciwnej strony.

4. Korekta różnic próbkowania:

Ta=-sqrt(sum((Vertices-Vertices(Na,:)).^2,2));
Tb=sqrt(sum((Vertices-Vertices(Nb,:)).^2,2)); 

Ta(checkNa)=-Ta(checkNa); Tb(checkNb)=-Tb(checkNb);
  • Oblicza odległości do sąsiadów, uwzględniając brakujące wartości.

5. Dopasowanie wielomianu do wierzchołków:

x = [Vertices(Na,1) Vertices(:,1) Vertices(Nb,1)]; y = [Vertices(Na,2) Vertices(:,2) Vertices(Nb,2)]; M = [ones(size(Tb)) -Ta Ta.^2 ones(size(Tb)) zeros(size(Tb)) zeros(size(Tb)) ones(size(Tb)) -Tb Tb.^2]; invM=inverse3(M); a(:,1)=invM(:,1,1).*x(:,1)+invM(:,2,1).*x(:,2)+invM(:,3,1).*x(:,3); a(:,2)=invM(:,1,2).*x(:,1)+invM(:,2,2).*x(:,2)+invM(:,3,2).*x(:,3); a(:,3)=invM(:,1,3).*x(:,1)+invM(:,2,3).*x(:,2)+invM(:,3,3).*x(:,3); b(:,1)=invM(:,1,1).*y(:,1)+invM(:,2,1).*y(:,2)+invM(:,3,1).*y(:,3); b(:,2)=invM(:,1,2).*y(:,1)+invM(:,2,2).*y(:,2)+invM(:,3,2).*y(:,3); b(:,3)=invM(:,1,3).*y(:,1)+invM(:,2,3).*y(:,2)+invM(:,3,3).*y(:,3);

  • Dopasowuje wielomiany do współrzędnych punktów, biorąc pod uwagę sąsiadów.

6. Obliczenie krzywizny:

k = 2*(a(:,2).*b(:,3)-a(:,3).*b(:,2)) ./ ((a(:,2).^2+b(:,2).^2).^(3/2));

7. Odwracanie macierzy 3x3:

function  Minv  = inverse3(M)
adjM(:,1,1)=  M(:,5).*M(:,9)-M(:,8).*M(:,6);
adjM(:,1,2)=  -(M(:,4).*M(:,9)-M(:,7).*M(:,6));
adjM(:,1,3)=  M(:,4).*M(:,8)-M(:,7).*M(:,5);
adjM(:,2,1)=  -(M(:,2).*M(:,9)-M(:,8).*M(:,3));
adjM(:,2,2)=  M(:,1).*M(:,9)-M(:,7).*M(:,3);
adjM(:,2,3)=  -(M(:,1).*M(:,8)-M(:,7).*M(:,2));
adjM(:,3,1)=  M(:,2).*M(:,6)-M(:,5).*M(:,3);
adjM(:,3,2)=  -(M(:,1).*M(:,6)-M(:,4).*M(:,3));
adjM(:,3,3)=  M(:,1).*M(:,5)-M(:,4).*M(:,2);
detM=M(:,1).*M(:,5).*M(:,9)-M(:,1).*M(:,8).*M(:,6)-M(:,4).*M(:,2).*M(:,9)+M(:,4).*M(:,8).*M(:,3)+M(:,7).*M(:,2).*M(:,6)-M(:,7).*M(:,5).*M(:,3);
Minv=bsxfun(@rdivide,adjM,detM);

Lista zmiennych i ich opis:

Vertices:

  • Typ: Macierz M x 2
  • Opis: Współrzędne punktów (wierzchołków) linii.

Lines:

  • Typ: Macierz N x 2
  • Opis: Lista odcinków linii, zdefiniowana przez indeksy punktów w Vertices.

Na:

  • Typ: Wektor M x 1
  • Opis: Indeksy lewych sąsiadów dla każdego punktu.

Nb:

  • Typ: Wektor M x 1
  • Opis: Indeksy prawych sąsiadów dla każdego punktu.

checkNa, checkNb:

  • Typ: Wektory logiczne M x 1
  • Opis: Wskazuje, które punkty nie mają lewego lub prawego sąsiada.

Naa, Nbb:

  • Typ: Wektory M x 1
  • Opis: Kopie Na i Nb, używane do uzupełniania braków.

Ta, Tb:

  • Typ: Wektory M x 1
  • Opis: Odległości do lewych i prawych sąsiadów.

x, y:`

  • Typ: Macierze M x 3
  • Opis: Współrzędne x i y dla punktów i ich sąsiadów.

M:

  • Typ: Macierz M x 9
  • Opis: Macierz współczynników dla dopasowania wielomianu.

invM:

  • Typ: Macierz M x 3 x 3
  • Opis: Odwrotność macierzy M.

a, b:

  • Typ: Macierze M x 3
  • Opis: Współczynniki wielomianów dopasowanych do współrzędnych x i y.

k:

  • Typ: Wektor M x 1
  • Opis: Wartości krzywizny dla punktów Vertices.

2.8 - Linia Znormalizowana 2D

Funkcja LineNormals2D oblicza normalne do punktów linii, wykorzystując sąsiednie punkty każdego punktu konturu oraz różnice w przód i w tył na końcach.

Wejście i wyjście:

Fragment kodu przyjmuje listę punktów/wierzchołków V o wymiarach 2 x M jako dane wejściowe. Opcjonalnie można podać listę odcinków Lines, która jest listą N x 2 zawierającą indeksy wierzchołków definiujących poszczególne odcinki linii (jeśli nie jest podana, zakłada się, że Lines=[1 2; 2 3 ; ... ; M-1 M]). Jako wynik zwraca normalne do wierzchołków N o wymiarach 2 x M.

  • V = Lista punktów/wierzchołków w postaci macierzy 2 x M.
  • Lines (opcjonalny) = Lista o wymiarach N x 2 zawierająca odcinki linii, wyrażone przez indeksy wierzchołków (jeśli nie jest podana, zakładamy, że Lines=[1 2; 2 3 ; ... ; M-1 M]).
  • N = Normalne do wierzchołków w postaci macierzy 2 x M.

Przykład:

Ten fragment kodu to przykładowe użycie funkcji LineNormals2D w celu obliczenia normalnych do linii na płaszczyźnie 2D. Dane wejściowe są wczytywane z pliku testowego (testdata). Następnie funkcja LineNormals2D jest wywoływana, aby obliczyć normalne do linii na podstawie podanych wierzchołków (Vertices) i odcinków (Lines). Otrzymane normalne są następnie wykorzystywane do wygenerowania wykresu, który przedstawia oryginalne linie oraz normalne do tych linii, przedstawione jako linie przechodzące przez wierzchołki i skierowane w kierunku normalnej zwiększonej dziesięciokrotnie.

  • testdata = nazwa pliku testowego.

FUNKCJA:

Funkcja napisana przez D. Kroona z Uniwersytetu w Twente (sierpień 2011)

Początek kodu odpowiada za ustalenie listy odcinków linii w przypadku, gdy nie są podane indeksy linii. Lista zmiennych:

  • nargin = Liczba argumentów wejściowych funkcji.
  • Lines = Lista odcinków linii, gdzie każdy odcinek jest połączeniem kolejnych punktów. Jeśli nie są podane indeksy linii, ta lista jest automatycznie generowana.

Obliczanie wektorów stycznych do krzywej poprzez różnicę pomiędzy współrzędnymi punktów końcowych i początkowych odcinków linii.

  • Lines(:,1) = indeksy początkowych punktów odcinków linii.
  • Lines(:,2) = indeksy końcowych punktów odcinków linii.
  • Vertices(Lines(:,1),:) = współrzędne początkowych punktów odcinków linii.
  • Vertices(Lines(:,2),:) = współrzędne końcowych punktów odcinków linii.

Wpływ wektorów stycznych na odległość dla każdego punktu/wierzchołka krzywej:

  • LL: Obliczana jest długość wektorów stycznych DT za pomocą funkcji sqrt(DT(:,1).^2+DT(:,2).^2).

  • DT(:,1)=DT(:,1)./max(LL.^2,eps): Normalizowane są współrzędne x wektorów stycznych przez kwadrat długości wektora (LL), z tym że minimalna wartość to eps (najmniejsza wartość reprezentowalna w danej precyzji arytmetyki).

  • DT(:,2)=DT(:,2)./max(LL.^2,eps): Normalizowane są współrzędne y wektorów stycznych przez kwadrat długości wektora (LL), z tym że minimalna wartość to eps.

  • D1=zeros(size(Vertices)); D1(Lines(:,1),:)=DT;: Tworzona jest macierz zerowa D1 o takim samym rozmiarze jak lista punktów/wierzchołków. Następnie wiersze odpowiadające początkowym punktom odcinków linii otrzymują wartości wektorów stycznych DT.

  • D2=zeros(size(Vertices)); D2(Lines(:,2),:)=DT;: Tworzona jest macierz zerowa D2 o takim samym rozmiarze jak lista punktów/wierzchołków. Następnie wiersze odpowiadające końcowym punktom odcinków linii otrzymują wartości wektorów stycznych DT.

  • D=D1+D2;: Sumowane są macierze D1 i D2, uzyskując macierz D, która zawiera wpływ wektorów stycznych na odległość dla każdego punktu/wierzchołka krzywej.

Normalizowanie wektorów normalnych:

  • LL: Obliczana jest długość wektorów normalnych D za pomocą funkcji sqrt(D(:,1).^2+D(:,2).^2).

  • N(:,1)=-D(:,2)./LL: Współrzędna x normalizowanego wektora normalnego jest ujemnym ilorazem współrzędnej y wektora normalnego przez długość LL.

  • N(:,2)= D(:,1)./LL: Współrzędna y normalizowanego wektora normalnego jest ilorazem współrzędnej x wektora normalnego przez długość LL.

Ostatecznie macierz N zawiera znormalizowane wektory normalne.

2.9 - Maksymalna prędkość na łuku

Opis kodu wyliczającego maksymalną prędkość bolidu na łuku korzystając z pliku zawierającego parametryczny opis opon i pliku opisującego model aerodynamiczny bolidu.

Opisany plik: Find_maximum_corner_speed.m

  • Czyszczenie środowiska
clear all
close all

Te dwie linie służą do czyszczenia środowiska MATLAB. clear all usuwa wszystkie zmienne z przestrzeni roboczej, a close all zamyka wszystkie otwarte okna graficzne.

  • Wczytywanie danych
load('Aero Downforce Daten.mat');    % Aero Daten

Ta linia wczytuje dane dotyczące sił aerodynamicznych z pliku .mat.

  • Wczytywanie danych opon
FileNameLocation = ('C19_CONTINENTAL_FORMULASTUDENT_205_470_R13_65kPa.tir');
TIRparam = loadTIR(FileNameLocation);

Te dwie linie wczytują dane o oponach z pliku .tir za pomocą funkcji loadTIR.

  • Inicjalizacja zmiennych
R = 10;
m = 280;
FZ_stat = 800;
k = 0;

Te linie inicjalizują zmienne używane w późniejszych obliczeniach. R to promień, m to masa, FZ_stat to statyczne obciążenie pionowe, a k to krok iteracji.

  • Pętla główna
for i = 1:8
    v1 = 5;
    v2 = 100;
    FZ_stat = 800 + (i-1)*200;
    ...
end

Ta pętla wykonuje obliczenia dla różnych wartości obciążenia pionowego. W każdej iteracji, FZ_stat jest zwiększane o 200 jednostek.

  • Obliczenia w pętli
while v1 < v2
    v1 = v1 + k;        
    Faero = interp1(v,FA,v1*3.6,'linear','extrap'); % [N] Abtriebskraft interpoliert        
    FZ(i) = FZ_stat + Faero/2;       
    v2 = sqrt(max(MF52_Fy_cs(0:-0.1:-12,FZ(i),0,0,TIRparam))*R/m);        
    k = k+0.0001;
end

Wewnątrz pętli głównej znajduje się pętla while, która wykonuje obliczenia dla danego obciążenia pionowego, dopóki pewien warunek nie zostanie spełniony. W każdej iteracji, v1 jest zwiększane o k, a k jest zwiększane o 0.0001.

  • Interpolacja siły aerodynamicznej
Faero = interp1(v,FA,v1*3.6,'linear','extrap'); % [N] Abtriebskraft interpoliert

Ta linia interpoluje siłę aerodynamiczną (Faero) na podstawie prędkości (v1).

  • Obliczanie obciążenia pionowego
FZ(i) = FZ_stat + Faero/2;

Ta linia oblicza obciążenie pionowe (FZ) na podstawie statycznego obciążenia pionowego (FZ_stat) i siły aerodynamicznej (Faero).

  • Obliczanie prędkości
v2 = sqrt(max(MF52_Fy_cs(0:-0.1:-12,FZ(i),0,0,TIRparam))*R/m);

Ta linia oblicza prędkość (v2) na podstawie obciążenia pionowego (FZ), promienia (R) i masy (m).

  • Obliczanie maksymalnego przyspieszenia bocznego
aQmax(i) = v2^2/R/9.81;

Ta linia oblicza maksymalne przyspieszenie boczne (aQmax) na podstawie prędkości (v2) i promienia (R).

  • Wykres wyników
scatter(FZ,aQmax)

Ta linia tworzy wykres punktowy (scatter plot), pokazujący maksymalne przyspieszenie boczne (aQmax) w funkcji obciążenia pionowego (FZ).

2.10 - Manadżer symulacji

simulationManager.m

Wstęp

simulationManager

Co się dzieje w ciele funkcji

  1. Na początku podejmowana jest próba przypisania zmiennej sensitivityID2 z klasy startingParameters załadowanej z pliku generateStartingParameters.m do zmiennej lokalnej o tej samej nazwie. Jeśli się nie uda przypisywana jest jej wartość “0”.

    W praktyce try powinien być wykonany, bo z pliku generateStartingParameters.m możemy wywnioskować, że w każdym przypadku będzie ta zmienna przechowywała jakąś wartość.


  1. Jeśli ilość kroków symulacji (numSteps) będzie większa od 1 oraz zmienna sensitivityID będzie różna od 0 (w praktyce; jeśli sensitivity analysis będzie wyłączone) to wykonuje się kod przedstawiony wyżej, gdzie funkcja zeros() tworzy tablicę o wymiarach 1 x numSteps wypełnioną zerami.

  1. W warunku mamy drugą wartość do śledzenia przy rysowaniu wykresu, czyli jeśli zaznaczony zostanie CheckBox włączający ją to warunek się spełni i wtedy:
    tic - uruchamia stoper
    wykonuje się pętla od 1 do numSteps z pętlą wewnętrzną z tym samym zakresem z przedstawionymi działaniami arytmetycznymi. Rezultatem tej pętli są wypiełnione tablice minValue i minValue2

    Ale jeśli warunek się nie spełni, czyli nie włączymy drugiej wartości do śledzenia to:
    tic - uruchamia stoper
    wykonuje się analogiczna pętla ale tylko dla minValue jak przedstawiono poniżej:


  1. Następnie zmienna steps jest zmniejszana o 1, żeby nie przekroczyć zakresu w następującej pętli równoległej, która do kolejnych komórek w tablicy result przypisuje wartości zwracane przez wywoływaną funkcję Vehiclesim_Endurance_GUI_Version() z parametrami
  • startingParameters
  • minValue()
  • minValue2()
  • sensitivityID
  • sensitivityID2

Do pliku z logami przez funkcję writeToLogfile zostaje zapisany czas wykonywania wszystkich powyższych operacji od momentu procedury tic do toc (zliczającej upłynięty czas).

Ładowana jest nazwa pliku z setupem.

Rezultaty są zapisywane do pliku .mat, dodając “_result” do nazwy, w tej samej lokalizacji co jest plik z setupem.

Jeśli jednak warunek 2. się nie spełni to wywoływana jest funkcja Vehiclesim_Endurance_GUI_Version(startingParameters).

2.11 - Parametry opon, poślizgi i siły

Opis parametryczny opon wraz z wyliczeniami poślizgów łączonych i czystych w osiach X i Y i sił działających na opony

Użyte pliki:

-Tires/C19_CONTINENTAL_FORMULASTUDENT_205_470_R13_65kPa.tir
-MF52_ALPHA_cs.m
-MF52_Fx_cs.m
-MF52_Fx_ps.m
-MF52_Fy_cs.m
-MF52_Fy_ps.m
-calculateLatTireforces.m
-calculateLongiTireForces.m
-calculateWheelloadLongDisp.m
-calculateWheelloadLatDisp.m
-calculateVTireStiff.m

Dokumentacja pliku parametrycznego opisu opony Continental

Plik zawiera parametryczny opis opony Continental, który jest używany do modelowania jej zachowania. Poniżej znajduje się dokumentacja poszczególnych sekcji tego pliku. WstępPlik zawiera informacje o marce opony, modelu, klasie, rozmiarze oraz innych parametrach fizycznych opony. Został wygenerowany przez Wilke Eikermanna i Hannesa Dettmanna z działu badań i rozwoju Continental Reifen Deutschland GmbH. Plik jest własnością Continental AG i jego dystrybucja jest możliwa tylko za wyraźnym zezwoleniem Continental AG lub jej spółek zależnych.

! : FILE_TYPE : TOF                                     
! : FILE_VERSION : 3                                       
! : TIRE_VERSION : MF-Tyre 5.2                             
!
! : COMMENT    : Tire Brand                                 CONTINENTAL                   
! : COMMENT    : Tire Trade                                 FORMULA STUDENT C19              
! : COMMENT    : Tire Class                                 Competition                    
! : COMMENT    : Tire Size                                  205/470 R13                    
! : COMMENT    : Tire Width                            [m]  0.200                         
! : COMMENT    : Tire Unloaded Radius                  [m]  0.235                         
! : COMMENT    : Tire Aspect Ratio                     [-]  0.34                           
! : COMMENT    : Rim Width                            [in]  7                             
! : COMMENT    : Rim Radius                            [m]  0.1651                        
! : COMMENT    : Inflation Pressure                  [kPa]  65                            

USE_MODE w modelu opony

USE_MODE to parametr w modelu opony, który określa, jakie obliczenia są wykonywane. Każda wartość USE_MODE odpowiada innemu zestawowi obliczeń:

  • 0: Oblicza tylko Fz (siłę pionową), nie wykonuje ewaluacji Magic Formula.
  • 1: Oblicza tylko Fx (siłę podłużną).
  • 2: Oblicza tylko Fy, Mx, Mz (siłę boczną, moment względem osi X i moment względem osi Z).
  • 3: Oblicza Fx, Fy, Mx, Mz bez kombinacji sił/momenty.
  • 4: Oblicza Fx, Fy, Mx, Mz z kombinacją sił/momenty. Dodanie 10 do dowolnej z powyższych wartości uwzględnia efekty relaksacji w obliczeniach. Na przykład, USE_MODE = 12 oznacza, że obliczenia są wykonywane tylko dla Fy, Mx, Mz i uwzględniają efekty relaksacji. Ważne jest, aby zauważyć, że model opony jest ważny tylko dla określonego USE_MODE. Inne tryby mogą nie dostarczyć dokładnych wyników, ponieważ model został skonstruowany do pracy w określonym trybie.

Jednostki

W pliku parametrycznym wszystkie dane podawane są w odniesieniu do jednostek układu SI

[UNITS]
LENGTH                    = 'meter'   
FORCE                     = 'newton'  
ANGLE                     = 'radians'
MASS                      = 'kg'      
TIME                      = 'second'

Model

Sekcja modelu zawiera informacje o typie modelu opony, wersji formatu pliku, stronie opony, trybie użycia i innych parametrach związanych z modelem opony.

[MODEL]
TYRESIDE                  = 'Right'   
PROPERTY_FILE_FORMAT      = 'MF_05'   
TYPE                      = 'TIR'     
FITTYP                    =           5    $typarr(  2)
USE_MODE                  =          14    $typarr(  1)
MFSAFE1                   =         121    $typarr(  3)
MFSAFE2                   =         121    $typarr(  4)
MFSAFE3                   =         242    $typarr(  5)
VXLOW                     = +1.000e+000    $typarr( 29)
LONGVL                    = +1.111e+001    $typarr( 30)

Wymiary

Sekcja wymiarów zawiera informacje o fizycznych wymiarach opony, takich jak promień opony bez obciążenia, szerokość opony, stosunek wysokości do szerokości, promień obręczy i szerokość obręczy.

[DIMENSION]
UNLOADED_RADIUS           = +2.350e-001    $typarr(  7)
WIDTH                     = +2.000e-001    $typarr(  8)
ASPECT_RATIO              = +3.400e-001    $typarr(  6)
RIM_RADIUS                = +1.651e-001    $typarr(  9)
RIM_WIDTH                 = +1.778e-001    $typarr( 10)

Kształt

Ten kod definiuje kształt opony za pomocą profilu bocznego opony wzdłuż jej szerokości. Każda linia reprezentuje punkt na profilu opony, gdzie pierwsza wartość to odległość od środka opony (wzdłuż promienia), a druga wartość to szerokość opony w tym punkcie.

  • 1.0 0.0 oznacza, że na początku (w środku opony), szerokość opony wynosi 0.0.
  • 1.0 0.4 oznacza, że gdy przechodzimy na zewnątrz opony, szerokość opony zwiększa się do 0.4.
  • 1.0 0.9 oznacza, że szerokość opony nadal rośnie, osiągając 0.9.
  • 0.9 1.0 oznacza, że na zewnątrz opony, szerokość opony osiąga swoje maksimum (1.0), ale odległość od środka opony nieznacznie się zmniejsza (0.9).

W ten sposób kod definiuje kształt opony jako profil boczny, który jest symetryczny względem osi opony. Wizualizacja tego kształtu przypominałaby krzywą, która jest szeroka na zewnątrz, ale zwęża się do środka opony.

[SHAPE]
{radial width}
 1.0    0.0
 1.0    0.4
 1.0    0.9
 0.9    1.0

Parametry pionowe

  • VERTICAL_STIFFNESS = Sztywność pionowa opony.
  • VERTICAL_DAMPING = Tłumienie pionowe opony.
  • BREFF = Parametr BREFF opony.
  • DREFF = Parametr DREFF opony.
  • FREFF = Parametr FREFF opony.
  • FNOMIN = Nominalna siła F opony.
[VERTICAL]
VERTICAL_STIFFNESS        = +8.600e+004    $typarr( 15)
VERTICAL_DAMPING          = +3.885e+003    $typarr( 16)
BREFF                     = +3.811E+000    $typarr( 11)
DREFF                     = +4.088e-001    $typarr( 12)
FREFF                     = +3.564e-002    $typarr( 13)
FNOMIN                    = +8.000e+002    $typarr( 14)

Zakresy

Sekcja: LONG_SLIP_RANGE

KPUMIN = -0.250e+000    $typarr( 23)
KPUMAX = +0.250e+000    $typarr( 24)
  • KPUMIN = Minimalna wartość długotrwałego poślizgu (KPU) dla opony.
  • KPUMAX = Maksymalna wartość długotrwałego poślizgu (KPU) dla opony.

Sekcja: SLIP_ANGLE_RANGE

ALPMIN = -2.094e-001    $typarr( 25)
ALPMAX = +2.094e-001    $typarr( 26)
  • ALPMIN = Minimalny kąt poślizgu (ALP) dla opony.
  • ALPMAX = Maksymalny kąt poślizgu (ALP) dla opony.

Sekcja: INCLINATION_ANGLE_RANGE

CAMMIN = -1.047e-001    $typarr( 27)
CAMMAX = +1.047e-001    $typarr( 28)
  • CAMMIN = Minimalny kąt nachylenia (CAM) dla opony.
  • CAMMAX = Maksymalny kąt nachylenia (CAM) dla opony.

Sekcja: VERTICAL_FORCE_RANGE

FZMIN = +2.286e+002    $typarr( 21)
FZMAX = +1.600e+003    $typarr( 22)
  • FZMIN = Minimalna siła pionowa (FZ) dla opony.
  • FZMAX = Maksymalna siła pionowa (FZ) dla opony.

Współczynniki

Współczynniki skalujące

LFZO  = 1  # Współczynnik skalowania nominalnego (ocenianego) obciążenia
LCX   = 1  # Współczynnik skalowania kształtu Fx
LMUX  = 1  # Współczynnik skalowania szczytowego współczynnika tarcia Fx
LEX   = 1  # Współczynnik skalowania czynnika krzywizny Fx
LKX   = 1  # Współczynnik skalowania sztywności poślizgu Fx
LHX   = 0  # Współczynnik skalowania przesunięcia poziomego Fx
LVX   = 0  # Współczynnik skalowania przesunięcia pionowego Fx
LGAX  = 1  # Współczynnik skalowania skrętu dla Fx
LCY   = 1  # Współczynnik skalowania kształtu Fy
LMUY  = 1  # Współczynnik skalowania szczytowego współczynnika tarcia Fy
LEY   = 1  # Współczynnik skalowania czynnika krzywizny Fy
LKY   = 1  # Współczynnik skalowania sztywności skrętnej Fy
LHY   = 0  # Współczynnik skalowania przesunięcia poziomego Fy
LVY   = 0  # Współczynnik skalowania przesunięcia pionowego Fy
LGAY  = 1  # Współczynnik skalowania skrętu dla Fy
LTR   = 1  # Współczynnik skalowania szczytu śladu pneumatycznego
LRES  = 0  # Współczynnik skalowania przesunięcia momentu resztkowego
LGAZ  = 1  # Współczynnik skalowania skrętu dla Mz
LXAL  = 1  # Współczynnik skalowania wpływu alfa na Fx
LYKA  = 1  # Współczynnik skalowania wpływu alfa na Fy
LVYKA = 1  # Współczynnik skalowania Fy indukowanego przez kappę
LS    = 1  # Współczynnik skalowania ramienia momentu Fx
LSGKP = 1  # Nie zdefiniowano
LSGAL = 1  # Nie zdefiniowano
LGYR  = 1  # Nie zdefiniowano
LMX   = 1  # Współczynnik skalowania momentu wywracającego
LVMX  = 0  # Współczynnik skalowania przesunięcia pionowego Mx
LMY   = 1  # Współczynnik skalowania momentu oporu toczenia  

Współczynniki w płaszczyźnie wzdłużnej i poprzecznej

Współczynniki w płaszczyźnie wzdłużnej opisują zachowanie opony podczas poślizgu podłużnego, zarówno w stanie czystego poślizgu, jak i poślizgu łączonego.

[LONGITUDINAL_COEFFICIENTS]
% Współczynniki - poślizg podłużny (poślizg czysty)
PCX1 = +1.786E+000 $typarr(61) % Współczynnik kształtu Cfx dla siły podłużnej
PDX1 = +2.933E+000 $typarr(62) % Tarcie podłużne Mux przy Fznom
PDX2 = -4.400E-001 $typarr(63) % Zmienność tarcia Mux z obciążeniem
PDX3 = +2.080E+001 $typarr(60) % Zmienność tarcia Mux z pochyleniem
PEX1 = +8.710E-001 $typarr(64) % Krzywizna podłużna Efx przy Fznom
PEX2 = -3.800E-002 $typarr(65) % Zmienność krzywizny Efx z obciążeniem
PEX3 = +0.000E+000 $typarr(66) % Zmienność krzywizny Efx z kwadratem obciążenia
PEX4 = +7.100E-002 $typarr(67) % Czynnik w krzywiznie Efx podczas jazdy
PKX1 = +8.531E+001 $typarr(68) % Sztywność poślizgu podłużnego Kfx/Fz przy Fznom
PKX2 = -2.025E+001 $typarr(69) % Zmienność sztywności poślizgu Kfx/Fz z obciążeniem
PKX3 = +5.000E-001 $typarr(70) % Wykładnik w sztywności poślizgu Kfx/Fz z obciążeniem
PHX1 = +0.000E+000 $typarr(71) % Przesunięcie poziome Shx przy Fznom
PHX2 = +0.000E+000 $typarr(72) % Zmienność przesunięcia Shx z obciążeniem
PVX1 = +0.000E+000 $typarr(73) % Przesunięcie pionowe Svx/Fz przy Fznom
PVX2 = +0.000E+000 $typarr(74) % Zmienność przesunięcia Svx/Fz z obciążeniem

% Współczynniki - poślizg podłużny (poślizg łączony)
RBX1 = +2.372E+001 $typarr(75) % Czynnik nachylenia dla redukcji Fx poślizgu łączonego
RBX2 = +2.597E+001 $typarr(76) % Zmienność nachylenia redukcji Fx z kappa
RCX1 = +7.495E-001 $typarr(77) % Czynnik kształtu dla redukcji Fx poślizgu łączonego
REX1 = -4.759E-001 $typarr(82) % Czynnik krzywizny łączonego Fx
REX2 = +8.109E-001 $typarr(83) % Czynnik krzywizny łączonego Fx z obciążeniem
RHX1 = +0.000E+000 $typarr(78) % Czynnik przesunięcia dla redukcji Fx poślizgu łączonego

Współczynniki w płaszczyźnie poprzecznej opisują zachowanie opony podczas poślizgu poprzecznego, zarówno w stanie czystego poślizgu, jak i poślizgu łączonego.

[LATERAL_COEFFICIENTS]
% Współczynniki - poślizg poprzeczny (poślizg czysty)
PCY1 = +1.725E+000 $typarr(91) % Współczynnik kształtu Cfx dla siły podłużnej
PDY1 = +2.733E+000 $typarr(92) % Tarcie podłużne Mux przy Fznom
PDY2 = -6.022E-001 $typarr(93) % Zmienność tarcia Mux z obciążeniem
PDY3 = +4.007E+000 $typarr(94) % Zmienność tarcia Mux z pochyleniem
PEY1 = -5.000E-001 $typarr(95) % Krzywizna podłużna Efx przy Fznom
PEY2 = -2.000E+000 $typarr(96) % Zmienność krzywizny Efx z obciążeniem
PEY3 = +2.260E-001 $typarr(97) % Zmienność krzywizny Efx z kwadratem obciążenia
PEY4 = -3.367E-002 $typarr(98) % Czynnik w krzywiznie Efx podczas jazdy
PKY1 = -5.047E+001 $typarr(99) % Sztywność poślizgu podłużnego Kfx/Fz przy Fznom
PKY2 = +1.923E+000 $typarr(100) % Zmienność sztywności poślizgu Kfx/Fz z obciążeniem
PKY3 = +2.877E-001 $typarr(101) % Wykładnik w sztywności poślizgu Kfx/Fz z obciążeniem
PHY1 = +0.000E+000 $typarr(102) % Przesunięcie poziome Shx przy Fznom
PHY2 = +0.000E+000 $typarr(103) % Zmienność przesunięcia Shx z obciążeniem
PHY3 = -1.810E-002 $typarr(104) % Zmienność przesunięcia Shx z obciążeniem
PVY1 = +0.000E+000 $typarr(105) % Przesunięcie pionowe Svx/Fz przy Fznom
PVY2 = +0.000E+000 $typarr(106) % Zmienność przesunięcia Svx/Fz z obciążeniem
PVY3 = -2.649E+000 $typarr(107) % Przesunięcie pionowe Svx/Fz przy Fznom
PVY4 = -1.058E+000 $typarr(108) % Zmienność przesunięcia Svx/Fz z obciążeniem

% Współczynniki - poślizg poprzeczny (poślizg łączony)
RBY1 = +2.033E+001 $typarr(109) % Czynnik nachylenia dla redukcji Fx poślizgu łączonego
RBY2 = +8.152E+000 $typarr(110) % Zmienność nachylenia redukcji Fx z kappa
RBY3 = -1.243E-002 $typarr(111) % Zmienność nachylenia redukcji Fx z kappa
RCY1 = +9.317E-001 $typarr(112) % Czynnik kształtu dla redukcji Fx poślizgu łączonego
REY1 = -3.982E-004 $typarr(113) % Czynnik krzywizny łączonego Fx
REY2 = +3.077E-001 $typarr(114) % Czynnik krzywizny łączonego Fx z obciążeniem
RHY1 = +0.000E+000 $typarr(115) % Czynnik przesunięcia dla redukcji Fx poślizgu łączonego
RHY2 = +0.000E+000 $typarr(116) % Czynnik przesunięcia dla redukcji Fx poślizgu łączonego
RVY1 = +0.000E+000 $typarr(117) % Czynnik przesunięcia dla redukcji Fx poślizgu łączonego
RVY2 = +0.000E+000 $typarr(118) % Czynnik przesunięcia dla redukcji Fx poślizgu łączonego
RVY3 = +0.000E+000 $typarr(119) % Czynnik przesunięcia dla redukcji Fx poślizgu łączonego
RVY4 = +0.000E+000 $typarr(120) % Czynnik przesunięcia dla redukcji Fx poślizgu łączonego
RVY5 = +0.000E+000 $typarr(121) % Czynnik przesunięcia dla redukcji Fx poślizgu łączonego
RVY6 = +0.000E+000 $typarr(122) % Czynnik przesunięcia dla redukcji Fx poślizgu łączonego
PTY1 = +3.260e+000 $typarr(123) % Czynnik przesunięcia dla redukcji Fx poślizgu łączonego
PTY2 = +2.250e+000 $typarr(124) % Czynnik przesunięcia dla redukcji Fx poślizgu łączonego

Współczynniki toczenia

QSY1 				= -3.090E-002			$typarr(126)
QSY2 				= -9.210E-002			$typarr(127)
QSY3 				= +0.000e+000			$typarr(128)
QSY4 				= +0.000e+000			$typarr(129)

Współczynniki nadsterowności (overturning)

QSX1 				= +0.000E+000			$typarr( 86)
QSX2 				= +1.269E+000			$typarr( 87)
QSX3 				= -2.807E-003			$typarr( 88)

Współczynniki korygujące (aligning)

QBZ1				= +6.895E+000			$typarr(131)
QBZ2				= +2.394E+000			$typarr(132)
QBZ3				= -3.945E+000			$typarr(133)
QBZ4				= +0.000E+000			$typarr(134)
QBZ5				= -1.369E-003			$typarr(135)
QBZ9				= +2.684E-007			$typarr(136)
QBZ10				= +1.994E+000			$typarr(130)
QCZ1				= +1.139E+000			$typarr(137)
QDZ1				= +1.396E-001			$typarr(138)
QDZ2				= -1.797E-002			$typarr(139)
QDZ3				= +0.000E+000			$typarr(140)
QDZ4				= -9.072E+000			$typarr(141)
QDZ6				= -2.000E-001			$typarr(142)
QDZ7				= +5.000E-001			$typarr(143)
QDZ8				= -1.406E+000			$typarr(144)
QDZ9				= +4.252E-001			$typarr(145)
QEZ1				= -9.783E+000			$typarr(146)
QEZ2				= +8.208E+000			$typarr(147)
QEZ3				= -2.000E+001			$typarr(148)
QEZ4				= -1.832E-001			$typarr(149)
QEZ5				= -6.352E+000			$typarr(150)
QHZ1				= +0.000E+000			$typarr(151)
QHZ2				= +0.000E+000			$typarr(152)
QHZ3				= +1.186E-001			$typarr(153)
QHZ4				= -5.376E-002			$typarr(154)
SSZ1				= +0.000E+000			$typarr(155)
SSZ2				= +4.650E-003			$typarr(156)
SSZ3				= -1.530E+000			$typarr(157)
SSZ4				= +0.000E+000			$typarr(158)
QTZ1				= +1.000E+000			$typarr(159)
MBELT				= +2.700E+000			$typarr(160)

Niestety nie znaleziono objaśnień dla współczynników toczenia, nadsterowności i korygujących.

Obliczenia poślizgów

Poślizg łączony w kierunku wzdłużnym

SHXA = RHX1;        
ALPHAS = ALPHA + SHXA;  
BXA = (RBX1 + RBX3 .* GAMMA^2) .* cos(atan(RBX2 .* KAPPA)) .* LXAL;
CXA = RCX1;
EXA = REX1 + REX2 * DFZ;
GXA0 = cos(CXA .* atan(BXA .* ALPHAS - EXA .* (BXA .* ALPHAS - atan(BXA .* ALPHAS))));
GXA = GXA0 ./ cos(CXA .*atan(BXA .* SHXA - EXA .* (BXA .* SHXA - atan(BXA .* SHXA))));

FX = FX0 .* GXA;    

SHXA = RHX1;
Ustawienie przesunięcia poziomego SHXA na wartość współczynnika RHX1, który opisuje przesunięcie poziome dla redukcji siły Fx przy poślizgu łączonym.

ALPHAS = ALPHA + SHXA;
Korekta kąta poślizgu (ALPHA) o przesunięcie poziome (SHXA), dając skorygowany kąt poślizgu ALPHAS.

BXA = (RBX1 + RBX3 .* GAMMA^2) .* cos(atan(RBX2 .* KAPPA)) .* LXAL;
Obliczenie BXA, czynnika nachylenia dla redukcji siły Fx przy poślizgu łączonym, z uwzględnieniem kąta nachylenia GAMMA, poślizgu KAPPA oraz współczynnika skalowania LXAL, wpływającego na Fx zależnie od kąta alfa.

CXA = RCX1;
Ustawienie CXA na wartość współczynnika RCX1, który określa kształt funkcji redukcji siły Fx przy poślizgu łączonym.

EXA = REX1 + REX2 * DFZ;
Obliczenie EXA, czynnika krzywizny łączonego Fx, z uwzględnieniem zmiany obciążenia pionowego opony DFZ.

GXA0 = cos(CXA .* atan(BXA .* ALPHAS - EXA .* (BXA .* ALPHAS - atan(BXA .* ALPHAS))));
Obliczenie GXA0, pierwotnej wartości funkcji kształtu siły Fx, na podstawie skorygowanego kąta poślizgu ALPHAS, czynnika nachylenia BXA, kształtu funkcji CXA i czynnika krzywizny EXA.

GXA = GXA0 ./ cos(CXA .*atan(BXA .* SHXA - EXA .* (BXA .* SHXA - atan(BXA .* SHXA))));
Normalizacja GXA0 poprzez podzielenie przez wartość korygującą, aby uwzględnić przesunięcie poziome SHXA w obliczeniach, dając końcową wartość funkcji kształtu siły Fx GXA.

FX = FX0 .* GXA;
Obliczenie końcowej siły poślizgu podłużnego FX, mnożąc pierwotną siłę podłużną FX0 przez funkcję kształtu GXA.

Czysty poślizg w kierunku wzdłużnym

GAMMAX = GAMMA .* LGAX;
SHX = (PHX1 + PHX2 .* DFZ) .* LHX;
KAPPAX = KAPPA + SHX;
CX = PCX1 .* LCX;
MUX = (PDX1 + PDX2 .* DFZ) .* (1 - PDX3 .* GAMMAX.^2) .* LMUX;
DX = MUX .* Fz;
EX = (PEX1 + PEX2 .* DFZ + PEX3 .* DFZ.^2) .* (1 - PEX4 .* sign(KAPPAX)) .* LEX;
KX = Fz .* (PKX1 + PKX2 .* DFZ) .* exp(PKX3 .* DFZ) .* LKX;
BX = KX ./ (CX .* DX);
SVX = Fz .* (PVX1 + PVX2 .* DFZ) .* LVX .* LMUX;

FX0 = DX .* sin(CX .* atan(BX .* KAPPAX - EX .* (BX .* KAPPAX - atan(BX .* KAPPA)))) + SVX;

FX = FX0;

GAMMAX = GAMMA .* LGAX;
Korekta kąta nachylenia GAMMA przez współczynnik skalowania LGAX, dając skorygowany kąt nachylenia GAMMAX.

SHX = (PHX1 + PHX2 .* DFZ) .* LHX;
Obliczenie przesunięcia poziomego SHX w oparciu o zmianę obciążenia pionowego DFZ i współczynnik skalowania LHX, uwzględniając podstawowe przesunięcie PHX1 i jego zmienność z DFZ (PHX2).

KAPPAX = KAPPA + SHX;
Korekta poślizgu KAPPA o przesunięcie poziome SHX, dając skorygowany poślizg KAPPAX.

CX = PCX1 .* LCX;
Ustawienie sztywności kształtu CX na podstawie podstawowego współczynnika PCX1 i współczynnika skalowania LCX.

MUX = (PDX1 + PDX2 .* DFZ) .* (1 - PDX3 .* GAMMAX.^2) .* LMUX;
Obliczenie szczytowego współczynnika tarcia MUX z uwzględnieniem zmiany obciążenia pionowego DFZ, skorygowanego kąta nachylenia GAMMAX, oraz współczynnika skalowania LMUX.

DX = MUX .* Fz;
Obliczenie siły podstawowej DX jako produkt szczytowego współczynnika tarcia MUX i obciążenia pionowego Fz.

EX = (PEX1 + PEX2 .* DFZ + PEX3 .* DFZ.^2) .* (1 - PEX4 .* sign(KAPPAX)) .* LEX;
Obliczenie czynnika krzywizny EX, uwzględniając zmianę obciążenia pionowego DFZ, znak skorygowanego poślizgu KAPPAX i współczynnik skalowania LEX.

KX = Fz .* (PKX1 + PKX2 .* DFZ) .* exp(PKX3 .* DFZ) .* LKX;
Obliczenie sztywności poślizgu KX jako funkcji obciążenia pionowego Fz, zmiany obciążenia DFZ i współczynnika skalowania LKX.

BX = KX ./ (CX .* DX);
Obliczenie sztywności kształtu BX jako stosunek sztywności poślizgu KX do iloczynu sztywności kształtu CX i siły podstawowej DX.

SVX = Fz .* (PVX1 + PVX2 .* DFZ) .* LVX .* LMUX;
Obliczenie przesunięcia pionowego SVX jako funkcji obciążenia pionowego Fz, zmiany obciążenia DFZ, współczynnika skalowania LVX oraz wpływu szczytowego współczynnika tarcia LMUX.

FX0 = DX .* sin(CX .* atan(BX .* KAPPAX - EX .* (BX .* KAPPAX - atan(BX .* KAPPA)))) + SVX;
Obliczenie siły poślizgu podłużnego FX0 z uwzględnieniem podstawowej siły DX, czynnika kształtu CX, sztywności kształtu BX, skorygowanego poślizgu KAPPAX, czynnika krzywizny EX oraz przesunięcia pionowego SVX.

FX = FX0;
Przypisanie ostatecznej wartości siły poślizgu podłużnego FX na podstawie obliczonej wartości FX0.

Poślizg łączony w kierunku poprzecznym

SHYK = RHY1 + RHY2 .* DFZ;       
KAPPAS = KAPPA + SHYK;
BYK = RBY1 .* cos(atan(RBY2 .* (ALPHA - RBY3))) .* LYKA;
CYK = RCY1;
EYK = REY1 + REY2 * DFZ;
DYK = FY0 ./ (cos(CYK .* atan(BYK .* SHYK - EYK .* (BYK .* SHYK - atan(BYK .* SHYK)))));
DVYK = MUY .* Fz .* (RVY1 + RVY2 .* DFZ + RVY3 .* GAMMA) .* cos(atan(RVY4 .* ALPHA));
SVYK = DVYK .* sin(RVY5 .* atan(RVY6 .* KAPPA)) .* LVYKA;
GYK0 = cos(CYK .* atan(BYK .* KAPPAS - EYK .* (BYK .* KAPPAS - atan(BYK .* KAPPAS))));
GYK = GYK0 ./ (cos(CYK .* atan(BYK .* SHYK - EYK .* (BYK .* SHYK - atan(BYK .* SHYK)))));

FY = FY0 .* GYK + SVYK;

SHYK = RHY1 + RHY2 .* DFZ;
Obliczenie przesunięcia poziomego SHYK na podstawie zmiany obciążenia pionowego DFZ i stałych RHY1 oraz RHY2.

KAPPAS = KAPPA + SHYK;
Korekta poślizgu KAPPA o przesunięcie poziome SHYK, dając skorygowany poślizg KAPPAS.

BYK = RBY1 .* cos(atan(RBY2 .* (ALPHA - RBY3))) .* LYKA;
Obliczenie współczynnika kształtu BYK dla bocznej siły poślizgu, uwzględniając kąt poślizgu ALPHA i współczynnik skalowania LYKA, który wpływa na relację między kątem poślizgu a siłą boczną.

CYK = RCY1;
Ustawienie wartości sztywności kształtu CYK na stałą RCY1.

EYK = REY1 + REY2 * DFZ;
Obliczenie czynnika krzywizny EYK w oparciu o zmianę obciążenia pionowego DFZ i stałe REY1 oraz REY2.

DYK = FY0 ./ (cos(CYK .* atan(BYK .* SHYK - EYK .* (BYK .* SHYK - atan(BYK .* SHYK)))));
Obliczenie siły podstawowej DYK dla bocznej siły poślizgu, korzystając z podstawowej wartości siły bocznej FY0 i korygując ją o czynniki kształtu BYK, sztywności CYK oraz krzywizny EYK.

DVYK = MUY .* Fz .* (RVY1 + RVY2 .* DFZ + RVY3 .* GAMMA) .* cos(atan(RVY4 .* ALPHA));
Obliczenie wartości pionowego przesunięcia DVYK na podstawie szczytowego współczynnika tarcia MUY, obciążenia pionowego Fz, zmiany obciążenia DFZ, kąta nachylenia GAMMA i kąta poślizgu ALPHA.

SVYK = DVYK .* sin(RVY5 .* atan(RVY6 .* KAPPA)) .* LVYKA;
Obliczenie dodatkowego składnika siły bocznej SVYK, który jest funkcją przesunięcia pionowego DVYK, poślizgu KAPPA oraz współczynnika skalowania LVYKA, wpływającego na siłę boczną indukowaną przez poślizg.

GYK0 = cos(CYK .* atan(BYK .* KAPPAS - EYK .* (BYK .* KAPPAS - atan(BYK .* KAPPAS))));
Obliczenie pierwotnej wartości funkcji kształtu siły bocznej GYK0, na podstawie korygowanego poślizgu KAPPAS, czynnika kształtu BYK, sztywności CYK oraz krzywizny EYK.

GYK = GYK0 ./ (cos(CYK .* atan(BYK .* SHYK - EYK .* (BYK .* SHYK - atan(BYK .* SHYK)))));
Normalizacja GYK0 przez podzielenie przez korektę, aby uwzględnić przesunięcie poziome SHYK w obliczeniach, dając końcową wartość funkcji kształtu siły bocznej GYK.

FY = FY0 .* GYK + SVYK;
Obliczenie końcowej bocznej siły poślizgu FY, mnożąc podstawową siłę boczną FY0 przez funkcję kształtu GYK i dodając składnik przesunięcia pionowego SVYK.

Czysty poślizg w kierunku poprzecznym

GAMMAY = GAMMA .* LGAY;
SHY = (PHY1 + PHY2 .* DFZ) .* LHY + PHY3 .* GAMMAY;
ALPHAY = ALPHA + SHY;
CY = PCY1 .* LCY;
MUY = (PDY1 + PDY2 .* DFZ) .* (1 - PDY3 .* GAMMAY.^2) .* LMUY;
DY = MUY .* Fz;
EY = (PEY1 + PEY2 .* DFZ) .* (1 - (PEY3 + PEY4 .* GAMMAY) .* sign(ALPHAY)) .* LEY;
KY = PKY1 .* FZ0 .* sin(2 * atan(Fz ./ (PKY2 .* FZ0 .* LFZO))) .* (1 - PKY3 .* abs(GAMMAY)) .* LFZO .* LKY;
BY = KY ./ (CY .* DY);
SVY = Fz .* ((PVY1 + PVY2 .* DFZ) .* LVY + (PVY3 + PVY4 .* DFZ) .* GAMMAY) .* LMUY;

FY0 = DY .* sin(CY .* atan(BY .* ALPHAY - EY .* (BY .* ALPHAY - atan(BY .* ALPHAY)))) + SVY;

FY = FY0;

GAMMAY = GAMMA .* LGAY;
Skorygowany kąt nachylenia GAMMAY, który uwzględnia współczynnik skalowania LGAY.

SHY = (PHY1 + PHY2 .* DFZ) .* LHY + PHY3 .* GAMMAY;
Przesunięcie poziome SHY, które uwzględnia zmianę obciążenia pionowego (DFZ), skorygowany kąt nachylenia (GAMMAY), oraz współczynniki skalowania LHY i PHY3.

ALPHAY = ALPHA + SHY;
Skorygowany kąt poślizgu ALPHAY, który uwzględnia przesunięcie poziome SHY.

CY = PCY1 .* LCY;
Sztywność kształtu CY, obliczona na podstawie współczynnika PCY1 i współczynnika skalowania LCY.

MUY = (PDY1 + PDY2 .* DFZ) .* (1 - PDY3 .* GAMMAY.^2) .* LMUY;
Szczytowy współczynnik tarcia MUY, który uwzględnia zmianę obciążenia pionowego (DFZ), skorygowany kąt nachylenia (GAMMAY), oraz współczynnik skalowania LMUY.

DY = MUY .* Fz;
Podstawowa siła DY, obliczona jako produkt szczytowego współczynnika tarcia MUY i obciążenia pionowego Fz.

EY = (PEY1 + PEY2 .* DFZ) .* (1 - (PEY3 + PEY4 .* GAMMAY) .* sign(ALPHAY)) .* LEY;
Czynnik krzywizny EY, który uwzględnia zmianę obciążenia pionowego (DFZ), skorygowany kąt nachylenia (GAMMAY), znak skorygowanego kąta poślizgu (ALPHAY), oraz współczynnik skalowania LEY.

KY = PKY1 .* FZ0 .* sin(2 * atan(Fz ./ (PKY2 .* FZ0 .* LFZO))) .* (1 - PKY3 .* abs(GAMMAY)) .* LFZO .* LKY;
Sztywność KY, obliczona na podstawie nominalnego obciążenia pionowego FZ0, obciążenia pionowego Fz, skorygowanego kąta nachylenia (GAMMAY), oraz współczynników skalowania LFZO i LKY.

BY = KY ./ (CY .* DY);
Stosunek sztywności BY, obliczony jako stosunek sztywności KY do iloczynu sztywności kształtu CY i podstawowej siły DY.

SVY = Fz .* ((PVY1 + PVY2 .* DFZ) .* LVY + (PVY3 + PVY4 .* DFZ) .* GAMMAY) .* LMUY;
Przesunięcie pionowe SVY, które uwzględnia obciążenie pionowe Fz, zmianę obciążenia pionowego (DFZ), skorygowany kąt nachylenia (GAMMAY), oraz współczynniki skalowania LVY i LMUY.

FY0 = DY .* sin(CY .* atan(BY .* ALPHAY - EY .* (BY .* ALPHAY - atan(BY .* ALPHAY)))) + SVY;
Podstawowa siła boczna FY0, obliczona jako suma siły DY pomnożonej przez funkcję trygonometryczną, która uwzględnia sztywność kształtu CY, stosunek sztywności BY, skorygowany kąt poślizgu ALPHAY, czynnik krzywizny EY, oraz przesunięcie pionowe SVY.

FY = FY0;
Przypisanie ostatecznej wartości siły bocznej FY na podstawie obliczonej wartości FY0.

Poślizg Alfa w kierunku poprzecznym (czysty)

GAMMAY = GAMMA .* LGAY;
SHY = (PHY1 + PHY2 .* DFZ) .* LHY + PHY3 .* GAMMAY;
ALPHAY = ALPHA + SHY;
CY = PCY1 .* LCY;
MUY = (PDY1 + PDY2 .* DFZ) .* (1 - PDY3 .* GAMMAY.^2) .* LMUY;
DY = MUY .* Fz;
EY = (PEY1 + PEY2 .* DFZ) .* (1 - (PEY3 + PEY4 .* GAMMAY) .* sign(ALPHAY)) .* LEY;
KY = PKY1 .* FZ0 .* sin(2 * atan(Fz ./ (PKY2 .* FZ0 .* LFZO))) .* (1 - PKY3 .* abs(GAMMAY)) .* LFZO .* LKY;
BY = KY ./ (CY .* DY);
SVY = Fz .* ((PVY1 + PVY2 .* DFZ) .* LVY + (PVY3 + PVY4 .* DFZ) .* GAMMAY) .* LMUY;

FY0 = DY .* sin(CY .* atan(BY .* ALPHAY - EY .* (BY .* ALPHAY - atan(BY .* ALPHAY)))) + SVY;

FY = FY0;

GAMMAY = GAMMA .* LGAY;
Dostosowuje kąt nachylenia (GAMMA) przez współczynnik skalowania (LGAY), aby uwzględnić wpływ nachylenia na generowanie siły bocznej.

SHY = (PHY1 + PHY2 .* DFZ) .* LHY + PHY3 .* GAMMAY;
Oblicza poziome przesunięcie (SHY) krzywej siły bocznej spowodowane zmianą obciążenia pionowego (DFZ) i kątem nachylenia (GAMMAY), wykorzystując współczynniki skalowania LHY i PHY3.

ALPHAY = ALPHA + SHY;
Dostosowuje kąt poślizgu (ALPHA) o obliczone poziome przesunięcie (SHY), uwzględniając zmieniony efektywny kąt poślizgu ze względu na zmiany obciążenia i nachylenia.

CY = PCY1 .* LCY;
Określa współczynnik kształtu (CY) dla siły bocznej, uwzględniając podstawową wartość (PCY1) i współczynnik skalowania (LCY).

MUY = (PDY1 + PDY2 .* DFZ) .* (1 - PDY3 .* GAMMAY.^2) .* LMUY;
Oblicza szczytowy współczynnik tarcia (MUY) dla siły bocznej, uwzględniając zmianę obciążenia pionowego (DFZ), kwadrat kąta nachylenia (GAMMAY^2) i współczynnik skalowania LMUY.

DY = MUY .* Fz;
Oblicza podstawową siłę boczną (DY) poprzez pomnożenie szczytowego współczynnika tarcia (MUY) przez obciążenie pionowe (Fz).

EY = (PEY1 + PEY2 .* DFZ) .* (1 - (PEY3 + PEY4 .* GAMMAY) .* sign(ALPHAY)) .* LEY;
Określa czynnik krzywizny (EY) dla krzywej siły bocznej, biorąc pod uwagę zmianę obciążenia pionowego (DFZ), kąt nachylenia (GAMMAY), znak dostosowanego kąta poślizgu (ALPHAY) oraz współczynnik skalowania LEY.

KY = PKY1 .* FZ0 .* sin(2 * atan(Fz ./ (PKY2 .* FZ0 .* LFZO))) .* (1 - PKY3 .* abs(GAMMAY)) .* LFZO .* LKY;
Oblicza sztywność przy skręcaniu (KY), uwzględniając nominalne obciążenie pionowe (FZ0), rzeczywiste obciążenie pionowe (Fz), kąt nachylenia (GAMMAY) oraz współczynniki skalowania LFZO i LKY.

BY = KY ./ (CY .* DY);
Określa współczynnik sztywności (BY) dla krzywej siły bocznej na podstawie sztywności przy skręcaniu (KY), współczynnika kształtu (CY) i podstawowej siły bocznej (DY).

SVY = Fz .* ((PVY1 + PVY2 .* DFZ) .* LVY + (PVY3 + PVY4 .* DFZ) .* GAMMAY) .* LMUY;
Oblicza pionowe przesunięcie (SVY) krzywej siły bocznej ze względu na zmianę obciążenia pionowego (DFZ), kąt nachylenia (GAMMAY) i współczynniki skalowania LVY i LMUY.

FY0 = DY .* sin(CY .* atan(BY .* ALPHAY - EY .* (BY .* ALPHAY - atan(BY .* ALPHAY)))) + SVY;
Oblicza początkową siłę boczną (FY0) jako sumę siły (DY) pomnożonej przez funkcję trygonometryczną, uwzględniającą współczynnik kształtu (CY), współczynnik sztywności (BY), dostosowany kąt poślizgu (ALPHAY), czynnik krzywizny (EY) oraz pionowe przesunięcie (SVY).

FY = FY0;
Przypisuje końcową wartość siły bocznej (FY) na podstawie obliczonej wartości początkowej (FY0).

Obliczanie sił poprzecznych

Plik calculateLatTireforces.m zawiera funkcję służącą do obliczania maksymalnych sił bocznych (poprzecznych), które mogą być przenoszone przez opony pojazdu. Stworzona przez Erica Dorniedena z zespołu Baltic Racing, funkcja ta jest chroniona prawami autorskimi tej organizacji z roku 2021.

Obliczanie sił

Funkcja calculateLatTireforces przyjmuje jako argumenty siły pionowe działające na poszczególne koła pojazdu (FWZ_vl, FWZ_vr, FWZ_hl, FWZ_hr), kąt nachylenia opony względem podłoża (GAMMA), parametry opony (TIRparam), a także początkowe kąty poślizgu dla opon przednich (alpha_f) i tylnych (alpha_r). Zwraca maksymalne siły boczne dla każdego koła (FWYmax_fl, FWYmax_fr, FWYmax_rl, FWYmax_rr), całkowite siły boczne dla osi przedniej i tylnej (FWYmax_f, FWYmax_r), oraz obliczone kąty poślizgu dla opon przednich i tylnych (alpha_f, alpha_r).

Główna funkcja

W zależności od liczby argumentów, funkcja używa dwóch różnych metod obliczania sił bocznych:

  1. Dla ośmiu argumentów, obliczenia są bezpośrednie, wykorzystując funkcję MF52_Fy_cs do określenia maksymalnej siły bocznej dla każdej opony:

    FWYmax_fl = max(abs(MF52_Fy_cs(alpha_f,FWZ_vl,GAMMA,0,TIRparam)));
    
  2. Gdy liczba argumentów jest mniejsza niż osiem, funkcja przeprowadza iteracyjne obliczenia dla zakresu kątów poślizgu od 0 do 12 stopni (co 0,025 stopnia), wybierając wartość maksymalną i odpowiadający jej kąt poślizgu dla każdej opony:

    x = 0:0.025:12; % Zakres kątów poślizgu [deg]
    [FWYmax_fl, index] = max(abs(MF52_Fy_cs(x,FWZ_vl,GAMMA,0,TIRparam)));
    alpha_fl = x(index);
    

Wynikowe Siły Osi

Na koniec, funkcja sumuje siły boczne dla opon położonych po tej samej stronie osi, aby uzyskać całkowitą siłę boczną, jaką może przenieść oś przednia i tylna:

FWYmax_f = FWYmax_fl + FWYmax_fr; % [N] Maksymalna siła boczna osi przedniej

Obliczanie sił wzdłużnych

Plik calculateLongiTireforces.m zawiera funkcję do obliczania maksymalnych sił podłużnych, które mogą być przenoszone przez opony pojazdu. Autorem kodu jest Eric Dornieden z zespołu Baltic Racing, a prawa autorskie należą do Baltic Racing z 2021 roku.

Główna Funkcja

Funkcja calculateLongiTireforces akceptuje jako argumenty wejściowe siły pionowe działające na każde koło pojazdu (FWZ_vl, FWZ_vr, FWZ_hl, FWZ_hr), kąt nachylenia opony (GAMMA), parametry opon (TIRparam) oraz kąty poślizgu dla opon przednich (alpha_f) i tylnych (alpha_r). Funkcja zwraca maksymalne siły podłużne dla każdej z opon (FWXmax_fl, FWXmax_fr, FWXmax_rl, FWXmax_rr) oraz sumaryczne maksymalne siły podłużne dla osi przedniej i tylnej (FWXmax_f, FWXmax_r).

Obliczanie Sił

Funkcja wykorzystuje różne metody obliczania maksymalnych sił podłużnych w zależności od liczby przekazanych argumentów:

  1. Dla ośmiu argumentów funkcja bezpośrednio oblicza maksymalną siłę podłużną dla każdej opony, używając funkcji MF52_Fx_cs, która prawdopodobnie modeluje siły opon na podstawie danych takich jak kąt poślizgu, obciążenie pionowe, kąt przechylenia i parametry opony:

    FWXmax_fl = max(abs(MF52_Fx_cs(alpha_f,FWZ_vl,GAMMA,0:0.01:0.2,TIRparam)));
    
  2. Gdy liczba argumentów jest inna, funkcja zakłada kąt poślizgu równy zero i oblicza maksymalne siły podłużne dla każdej opony w oparciu o ten założony kąt poślizgu:

    FWXmax_fl = max(abs(MF52_Fx_cs(0,FWZ_vl,GAMMA,0:0.01:0.2,TIRparam)));
    

Wynikowe Siły Osi

Po obliczeniu maksymalnych sił podłużnych dla każdej opony, funkcja sumuje siły dla opon umieszczonych po tej samej stronie osi, aby określić całkowitą maksymalną siłę podłużną, którą może przenieść oś przednia i tylna:

FWXmax_f = FWXmax_fl + FWXmax_fr; % [N] Maksymalna siła podłużna osi przedniej  

Obciążenie dynamiczne w kierunku poprzecznym

Funkcja calculateWheelloadLatDisp oblicza przemieszczenie obciążenia koła w kierunku poprzecznym. Jest to kluczowy element w obliczaniu przeniesienia obciążenia koła.

Sygnatura funkcji

function [dFWZfl_y, dFWZfr_y, dFWZrl_y, dFWZrr_y, dFWZfl_geometric, dFWZfr_geometric, dFWZrl_geometric, dFWZrr_geometric, dFWZfl_elastic, dFWZfr_elastic, dFWZrl_elastic, dFWZrr_elastic] = calculateWheelloadLatDisp(h_COG, track_f, track_r, lr, lf, wheelbase, FVY, h_rc_f, h_rc_r)

Opis parametrów

  • h_COG: Wysokość środka ciężkości pojazdu.
  • track_f, track_r: Szerokość toru przedniego i tylnego koła.
  • lr, lf: Odległość od tylnego i przedniego końca pojazdu do środka ciężkości.
  • wheelbase: Rozstaw osi pojazdu.
  • FVY: Siła boczna działająca na pojazd.
  • h_rc_f, h_rc_r: Wysokość środka ciężkości przedniego i tylnego zawieszenia.

Opis działania

Funkcja oblicza przeniesienie obciążenia koła w kierunku poprzecznym na podstawie różnych parametrów pojazdu i sił działających na pojazd. Obliczenia są wykonywane dla każdego koła pojazdu.

  1. Przeniesienie obciążenia geometryczne:

    dFWZfl_geometric = -lr/wheelbase*FVY*h_rc_f/track_f;        % [N] Geometryczne przeniesienie obciążenia dla koła przedniego lewego
    dFWZfr_geometric = lr/wheelbase*FVY*h_rc_f/track_f;         % [N] Geometryczne przeniesienie obciążenia dla koła przedniego prawego
    dFWZrl_geometric = -lf/wheelbase*FVY*h_rc_r/track_r;        % [N] Geometryczne przeniesienie obciążenia dla koła tylnego lewego
    dFWZrr_geometric = lf/wheelbase*FVY*h_rc_r/track_r;         % [N] Geometryczne przeniesienie obciążenia dla koła tylnego prawego
    
  2. Przeniesienie obciążenia sprężyste:

    dFWZfl_elastic = -lr/wheelbase*FVY*(h_COG-h_rc_f)/track_f;  % [N] Elastyczne przeniesienie obciążenia dla koła przedniego lewego
    dFWZfr_elastic = lr/wheelbase*FVY*(h_COG-h_rc_f)/track_f;   % [N] Elastyczne przeniesienie obciążenia dla koła przedniego prawego
    dFWZrl_elastic = -lf/wheelbase*FVY*(h_COG-h_rc_r)/track_r;  % [N] Elastyczne przeniesienie obciążenia dla koła tylnego lewego
    dFWZrr_elastic = lf/wheelbase*FVY*(h_COG-h_rc_r)/track_r;   % [N] Elastyczne przeniesienie obciążenia dla koła tylnego prawego
    
  3. Dynamiczne przeniesienie obciążenia:

    dFWZfl_y = dFWZfl_geometric + dFWZfl_elastic;               % [N] Przeciążenie dynamiczne koła przedniego lewego
    dFWZfr_y = dFWZfr_geometric + dFWZfr_elastic;               % [N] Przeciążenie dynamiczne koła przedniego prawego
    dFWZrl_y = dFWZrl_geometric + dFWZrl_elastic;               % [N] Przeciążenie dynamiczne koła tylnego lewego
    dFWZrr_y = dFWZrr_geometric + dFWZrr_elastic;               % [N] Przeciążenie dynamiczne koła tylnego prawego
    

Obciążenie dynamiczne w kierunku wzdłużnym

Funkcja calculateWheelloadLongDisp oblicza dynamiczne przemieszczenie obciążenia koła w kierunku podłużnym. Jest to kluczowy element w obliczaniu przeniesienia obciążenia koła.

Sygnatura funkcji

function [dFWZfl_x, dFWZfr_x, dFWZrl_x, dFWZrr_x] = calculateWheelloadLongDisp(h_COG, m_ges, aVX, wheelbase)

Opis parametrów

  • h_COG: Wysokość środka ciężkości pojazdu.
  • m_ges: Masa całkowita pojazdu.
  • aVX: Przyspieszenie pojazdu w kierunku podłużnym.
  • wheelbase: Rozstaw osi pojazdu.

Opis działania

Funkcja oblicza dynamiczne przeniesienie obciążenia koła w kierunku podłużnym na podstawie różnych parametrów pojazdu i sił działających na pojazd. Obliczenia są wykonywane dla każdego koła pojazdu.

dFWZfl_x = -m_ges*aVX*h_COG/wheelbase

Sztywność pionowa opony

Funkcja calculateVtirestiff oblicza pionową sztywność opony dla każdego z czterech kół pojazdu.

Argumenty funkcji

Funkcja przyjmuje następujące argumenty:

  • Fz: Wektor sił pionowych dla różnych warunków.
  • cZ_tire: Wektor sztywności opony dla różnych warunków.
  • FWZ_fl, FWZ_fr, FWZ_rl, FWZ_rr: Siły pionowe działające na przednie lewe, przednie prawe, tylne lewe i tylne prawe koło pojazdu.

Działanie funkcji

Funkcja interpoluje sztywność opony (cZ_tire) na podstawie siły pionowej (Fz) dla każdego koła pojazdu. Interpolacja jest liniowa i ekstrapolowana poza zakres wektora Fz, jeśli to konieczne.

Wyniki funkcji

Funkcja zwraca cztery wartości: cZ_fl, cZ_fr, cZ_rl, cZ_rr, które reprezentują sztywność opony dla przedniego lewego, przedniego prawego, tylnego lewego i tylnego prawego koła pojazdu.

Snippet kodu

function [cZ_fl, cZ_fr, cZ_rl, cZ_rr] = calculateVtirestiff(Fz, cZ_tire, FWZ_fl, FWZ_fr, FWZ_rl, FWZ_rr)
    %% Vertical tire stiffness
    cZ_fl = interp1(Fz,cZ_tire,FWZ_fl,'linear','extrap'); % [N/m] Interpolated tire stiffness
    cZ_fr = interp1(Fz,cZ_tire,FWZ_fr,'linear','extrap'); % [N/m] Interpolated tire stiffness
    cZ_rl = interp1(Fz,cZ_tire,FWZ_rl,'linear','extrap'); % [N/m] Interpolated tire stiffness
    cZ_rr = interp1(Fz,cZ_tire,FWZ_rr,'linear','extrap'); % [N/m] Interpolated tire stiffness       
end

2.12 - Generowanie parametrów startowych

generateStartingParameters.m

Wstęp

Wyjaśnione są tutaj wszystkie parametry które ładowane są do klasy startingParameters, przekazywane dalej do funkcji simulationManager.m

Co się dzieje w ciele funkcji

  1. Na początku otwierany jest interfejs wyboru pliku. Zastosowany jest filtr na rozszerzenie pliku .mat. Do zmiennej carDatafile jest załadowywana nazwa wybranego pliku, a do zmiennej path jego ścieżka (bez nazwy samego pliku).

  2. Następnie do kolejnych zmiennych klasy startingParameters przypisywane są wartości pobrane z elementów interfejsu użytkownika (typu DropDown i CheckBox) i inne, jak przedstawiono poniżej:

Zmienna Co jest do niej przypisywane
disciplineID dyscyplina (z UI)
carDatafile carDatafile
path path
TrackFileName nazwa pliku toru
brakeFunction system hamulców (z UI)
logCellData informacja czy cell data zapisywać do pliku z logami
debugMessages informacja czy wypisywać logi do debugowania (z UI)
startingSpeed prędkość startowa dla wybranego toru
numOfLaps ilość okrążeń do przejechania dla wybranego toru
Debug wartość “0”

  1. Jeśli chcemy wyeksportować aplikację:
Zmienna Co jest do niej przypisywane
processDataButtonHandle przycisk rozpoczęcia symulacji
textAreaHandle pole tekstowe w zakładce “How-to”

W przeciwnym razie do obu tych zmiennych przypisywane są wartości “0”.


  1. Jeśli włączona jest analiza czułości:
Zmienna Co jest do niej przypisywane
sensitivityID co chcemy śledzić (z UI)
minValue minimalna wartość
stepSize rozmiar kroku
numSteps ilość kroków symulacji

Wewnątrz tej funkcji warunkowej występuje druga; jeśli zaznaczony jest CheckBox włączający drugi zestaw elementów UI to wyżej wymienione zmienne (poza numSteps) zostają powielone i przypisane do nich zostają wartości z odpowiadających im elementów UI.

W przeciwnym razie, przypisywane są do nich domyślne wartości “0” oraz dla numSteps “1”, co się tyczy zarówno pierwszej jak i drugiej funkcji warunkowej.


Na samym końcu wywoływana jest funkcja simulationManager() z parametrem klasa startingParameters czyli z całym zestawem zmiennych.

2.13 - Pliki .mat i .csv

Pliki .mat i .csv nie zawierają skryptów, są to zbiory danych jako wyniki symulacji, dane do symulacji czy parametryczne opisy tras.

Data Inspector

Folder zawiera pliki .csv i .mat, które są wynikami przeprowadzonych symulacji bądź danymi na których twórcy wzorowali się tworząc własną symulację.
Każdy plik z danymi o trasie ma inną strukturę a z danych wynika, że są to dane telemetryczne pojazdów podczas przejazdu na danej trasie, znajdują się tam między innymi informacje o temperaturach, balansie hamulców czy przeciążeniach.

Logged Data

Najważniejszym do analizy plikiem jest loggedDataTest.csv lub jego wariant loggedData.csv. Zawierają one informacje o przejazdach pojazdu po nieokreślonej w pliku trasie, jednak w nich najlepiej można zaobserwować zmiany parametrów pojazdu w trakcie jazdy.

Struktura pliku loggedDataTest

Struktura pliku loggedDataTest

Zdjęcie powyżej to fragment omawianego pliku, widać że są dane uzyskane z symulacji bądź zgrupowane dane z systemu telemetrycznego.

Trasy i przejazdy

Nurburgring.csv

Nurburgring.csv

Daytona.csv

Daytona.csv

Zdjęcia powyżej to przykady jak wygląda zbiór danych z przejazdu po trasie w przypadku pojazdów spoza klasy FORMULA STUDENT.

Dla przykładu plik Daytona.csv opisuje prędkości przejazdu po Daytonie przez Porsche 997. Kolejne kolumny pliku to prędkości notowane przez pojazd oraz przez GPS w różnych osiach, notowana jest także zmiana wysokości.

2.14 - oddziaływanie sił

działanie/obliczanie poszczególnych sił na pojazd

Wstęp

BrakeCalculation.mlx- opisywany plik, działanie poszczególnych funkcji

Działanie

  1. Zmienne wyświetlane na samym początku.

g = 9.81; - Przyspieszenie ziemskie w m/s^2. M = 282.283; - Masa pojazdu w kilogramach. prozF = 0.42582; - Procentowa masa na przedniej osi. prozR = 1 - prozF; - Procentowa masa na tylnej osi. Z = 2.3; - Współczynnik przesterowania. H = 250.338; - Wysokość środka ciężkości nad ziemią w milimetrach. l = 1530; - Środkowa odległość osi w milimetrach. lv = 878.488; - Odległość środka ciężkości pojazdu od tylnej osi w milimetrach. lh = 651.512; - Odległość środka ciężkości pojazdu od przedniej osi w milimetrach. MuR = 2.3; - Współczynnik tarcia hamulca. drV = 428; - Średnica tarczy hamulcowej przedniej w milimetrach. drH = 428; - Średnica tarczy hamulcowej tylnej w milimetrach. v = 100; - Prędkość pojazdu w km/h. dKv = 25; - Średnica tłoczka cylindra hamulcowego przedniego w milimetrach. dKh = 25; - Średnica tłoczka cylindra hamulcowego tylnego w milimetrach. diV = 199.742; - Średnica wewnętrzna tarczy hamulcowej przedniej w milimetrach. daV = 148.742; - Średnica zewnętrzna tarczy hamulcowej przedniej w milimetrach. diH = 147; - Średnica wewnętrzna tarczy hamulcowej tylnej w milimetrach. daH = 200; - Średnica zewnętrzna tarczy hamulcowej tylnej w milimetrach. MuBelag = 0.6; - Współczynnik tarcia klocków hamulcowych z tarczą. X = H / l; - Współczynnik dynamicznego rozkładu masy pojazdu.

  1. Funkcje z poszczególnymi zmiennymi oraz ich działanie.

Gesamtgewichtskraft(g, M) - Oblicza siłę ciężkości całego pojazdu.

MasseAchse(FG, proz) - Oblicza masę na osi.

Achslast(g, m) - Oblicza siłę nacisku na oś.

AchslastVorneDynamisch(FG, l, lh, Z, H) - Oblicza dynamiczne obciążenie osi przedniej.

AchslastHintenDynamisch(FG, l, lv, Z, H) - Oblicza dynamiczne obciążenie osi tylnej.

Bremskraft(FGDyn, MuR) - Oblicza siłę hamowania.

Bremsmoment(FBDyn, dr) - Oblicza moment hamowania.

AufGewichtskraftBezogeneDynBremskraftVorne(Z, H, X) - Oblicza dynamiczną siłę hamowania związana z obciążeniem osi przedniej.

AufGewichtskraftBezogeneDynBremskraftHinten(Z, H, X) - Oblicza dynamiczną siłę hamowania związana z obciążeniem osi tylnej.

VonDerBremseAufzunehmendeLeistung(M, MuR, g, v) - Oblicza moc, która musi być absorbowana przez hamulce.

KolbenflaecheVorne(dK) - Oblicza powierzchnię tłoczka cylindra hamulcowego przedniego.

KolbenflaecheHinten(dK) - Oblicza powierzchnię tłoczka cylindra hamulcowego tylnego.

BremszylinderFlaeche(dZ) - Oblicza powierzchnię cylindra hamulcowego.

EffektiverReibradius(di, da) - Oblicza efektywny promień tarczy hamulcowej.

Spannkraft(MB, MuBelag, rm) - Oblicza siłę nacisku na tarczę hamulcową.

Bremsdruck(FSP, AK) - Oblicza ciśnienie hamowania.

BetaetigungskraftBremszylinder(bremsdruck, AZ) - Oblicza siłę działającą na cylindry hamulcowe.

2.15 - Presety

Folder Presets zawiera pliki z przykładowymi wartościami technicznymi bolidu, jak również środowiskowymi np. temperatura i ciśnienie powietrza. Poniżej zostały opisane poszczególne zmienne. Pliki: TY19_HighDownforce.mat, TY19_LowDownforce.mat, TY19_MedDownforce.mat, TY19_NoDownforce.mat, TY20_HighDownforce.mat, TY20_LowDownforce.mat, TY20_MedDownforce.mat, TY20_NoDownforce.mat, TY22_HighDownforce.mat, TY22_LowDownforce.mat, TY22_MedDownforce.mat, TY22_NoDownforce.mat, loadSetup.m

Definicje zmiennych

Zmienna Definicja
m_ges masa pojazdu
h_cog wysokosc srodka ciezkosci
x_cog srodek masy w osi X
x_va polozenie przedniej osi
m_driver masa kierowcy
h_cog_driver wysokość środka ciężkości kierowcy
x_cog_driver położenie środka ciężkości kierowcy w osi x
m_ballast dociążenie kierowcy
h_cog_ballast wysokość środka ciężkości dociążenia kierowcy
x_cog_ballast położenie środka ciężkości dociążenia kierowcy
thetaV_X nieuzywane?
thetaV_Y nieuzywane?
thetaV_Z nieuzywane?
wheelbase rozstaw osi
track nieuzywane?
J_Tire nieuzywane?
p_Tire cisnienie opon
LMUX Longitudinal scaling factor
LMUY Lateral scaling factor
k_R uzyte: FR = k_R*FWZges; % [N] Rolling resistance
FB wartosc startowa symulacji
camber pochylenie kół
m_ph rozlozenie masy
ptype zmienna binarna uzywana jako warunek
p_max maksymalna moc silnika
n_max maksymalne obroty silnika
drivertrain_eff sprawnosc ukladu napedowego
invertor_eff sprawnosc falownika
z_chaindriver rozmiar zebatki po stronie kol
z_sprocket rozmiar zebatki po stronie silnika
trq_multiplier nieuzywane?
engine_param macierz parametrów silnika
num_motors liczba silnikow
gearbox zmienna do okreslenie czy jest wiecej niz jeden bieg
i_P cos z przelozeniem?
i_param macierz przełożeń dla kolejnych biegów
n_shift obroty silnika przy ktorych nastepuje zmiana biegu na wyzszy
n_downshift obroty silnika przy ktorych nastepuje zmiana biegu na nizszy
t_shift czas zmiany biegu
c_w wspolczynnik oporu powietrza
c_l wspolczynnik oporu powietrza
A powierzchnia przekroju bolidu???
downforce_data nieuzywane?
downforce_multiplier mnożnik sily dociskowej?
aero_pv uzyte: dFWZrl_aero = Faero/2*aero_ph; % [N] Aerodynamic force on rear left wheel
DRS czy DRS jest dostepny/wlaczony
c_d_DRS wspolczynnik oporu powietrza z wlaczonym drs
c_l_DRS wspolczynnik oporu powietrza z wlaczonym drs
ConstantDownforce stala sily docisku
DRS_Radius promien DRS?
V_i napiecie baterii
Energy_i nieuzywane?
nZellen_Parallel liczba celi baterii polaczonych rownolegle?
nZellen_Reihe liczba celi baterii polaczonych szeregowo?
capacity_cell pojemnosc celi baterii
t_L temperatura powietrza
p_L cisnienie atmosferyczne
R_L stala gazowa dla powietrza
g przyspieszenie ziemskie

Porównanie wartości w poszczególnych plikach

W przygotowaniu

Ładowanie setupów do symulacji

Plik loadSetup.m w katalogu głównym odpowiada za załadowanie wszystkich tych parametrów do symulacji.

Prototyp funkcji

function loadSetup(app, file)

Parametry

  • app: Obiekt aplikacji, do którego ładowane są parametry.
  • file: Ścieżka do pliku konfiguracyjnego .mat.

Działanie

Funkcja ładowania próbuje wczytać dane z pliku .mat i przypisuje je do właściwości obiektu app. Parametry są podzielone na kategorie takie jak szkielet, zawieszenie, napęd, aerodynamika, akumulator i warunki środowiskowe. Dodatkowo aplikacja sprawdza stan skrzyni biegów i zeruje jej przełożenia.

if app.gearbox
            setup.i_param = app.i_param;
            setup.n_shift = app.n_shift;
            setup.n_downshift = app.n_downshift;
            setup.t_shift = app.t_shift;
        else
            setup.i_param = [0 0];
            setup.n_shift = 0;
            setup.n_downshift = 0;
            setup.t_shift = 0;
        end

Obsługa błędów

W razie wystąpienia błędu podczas ładowania, funkcja zapisuje komunikat o błędzie do pliku dziennika.

Zastosowanie

Funkcja jest wywoływana z obiektem aplikacji i ścieżką do pliku konfiguracyjnego, inicjując aplikację z załadowanymi ustawieniami pojazdu.

2.16 - Wykresy sił na oponach

Opis skryptów badających siły przenoszone przez opony w zależności od poślizgu korzystając z paretrów opon Continental FormulaStudent 205 407 R13 65kPa

Wstęp

Realizacja wykresów opisujących zachowanie opon odbywa się za pomocą plików Conti_Tire_Plots_Lateral.m i Conti_Tire_Plots_Longitudinal.m opisujących siły w kierunku poprzedznym i wzdłużnym. Obydwa skrypty są bardzo podobne, jednakże znajdują się tam różnice w danych charakterystyczne dla opisywanego kierunku sił.

Analiza w kierunku poprzecznym

Zmienne:

Rys.1 Zmienne dla pliku  &hellip;Lateral.m

Rys.1 Zmienne dla pliku …Lateral.m

  • ALPHA: Jest to kąt poślizgu bocznego w stopniach. Kąt poślizgu bocznego jest to kąt między kierunkiem jazdy a kierunkiem, w którym opona jest skierowana.
  • GAMMA: Jest to kąt pochylenia w stopniach. Kąt pochylenia jest to kąt, pod którym opona jest pochylona względem pionu.
  • KAPPA: Jest to poślizg opony. Poślizg opony jest to różnica między prędkością obrotową opony a prędkością pojazdu.
  • FileNameLocation: Jest to ścieżka do pliku Tir. Plik Tir zawiera wszystkie parametry opony, które są potrzebne do modelowania jej zachowania.
  • TIRparam: Jest to struktura zawierająca parametry opony. Parametry te są wczytywane z pliku Tir.
  • Fz_r: Jest to obciążenie koła z tyłu w pozycji statycznej. Obciążenie to jest mierzone w niutonach.
  • Fy: Jest to przenoszona siła koła. Siła ta jest obliczana na podstawie parametrów opony i warunków jazdy.

Funkcje:

Rys.2 Funkcje dla pliku  &hellip;Lateral.m

Rys.2 Funkcje dla pliku …Lateral.m

  • loadTIR: Jest to funkcja, która wczytuje plik Tir do struktury. Plik Tir zawiera wszystkie parametry opony, które są potrzebne do modelowania jej zachowania.
  • MF52_Fy_cs: Jest to funkcja, która oblicza przenoszoną siłę koła. Funkcja ta oblicza siłę na podstawie parametrów opony i warunków jazdy.

Analiza w kierunku wzdłużnym

Funkcje i zmienne niewymienione poniżej są analogiczne jak opisane powyżej.

Zmienne:

Rys.3 Zmienne dla pliku  &hellip;Longitudinal.m

Rys.3 Zmienne dla pliku …Longitudinal.m

  • ALPHA: Kąt poślizgu bocznego w stopniach.
  • GAMMA: Kąt pochylenia w stopniach.
  • KAPPA: Poślizg opony.
  • FileNameLocation: Ścieżka do pliku Tir.
  • TIRparam: Struktura zawierająca parametry opony.
  • Fz_r: Obciążenie koła z tyłu w pozycji statycznej.
  • Fy / Fx: Przenoszona siła koła (boczna / podłużna).

Funkcje:

Rys.4 Funkcje dla pliku  &hellip;Longitudinal.m

Rys.4 Funkcje dla pliku …Longitudinal.m

  • loadTIR: Wczytuje plik Tir do struktury.
  • MF52_Fy_cs / MF52_Fx_cs: Oblicza przenoszoną siłę koła (boczną / podłużną).

Wykresy:

  • Pierwszy skrypt generuje wykres siły bocznej w zależności od kąta poślizgu bocznego i poślizgu podłużnego.
    Rys.5 Wykres rysowany przez plik &hellip;Longitudinal.m

    Rys.5 Wykres rysowany przez plik …Longitudinal.m

  • Drugi skrypt generuje wykres siły podłużnej w zależności od poślizgu opony i kąta poślizgu bocznego.
    Rys.6 Wykres rysowany przez plik   &hellip;Longitudinal.m

    Rys.6 Wykres rysowany przez plik …Longitudinal.m

Problemy:

Ze względu na brak kompletnych informacji na temat wielu zmiennych z pliku .tir opisującego parametry badanej opony na ten moment nie wiemy, jak zmieniane w obydwu skryptach parametry wpływają na wynik symulacji.

2.17 - catstruct.m

catstruct.m - łączenie struktur w jedną

Wstęp

Ta funkcja z pliku catstruct.m służy w skrócie do łączenia wielu struktur w jedną.

Działanie funkcji

narginchk() jest wykorzystwane do sprawdzenia czy ilość argumentów przesłanych do aktualnie wykonującej się funkcji mieści się w zadanym zakresie. Jeśli tak jest to nargin nic nie robi, natomiast jeśli liczba tych argumentów wyjdzie poza któryś z limitów to nargin wyrzuci błąd. W naszym przypadku ilość argumentów przesłanych do funkcji musi wynosić co najmniej 1. Zaraz potem do N jest przypisane nargin, które to zwraca ich ilość.

rys. 1

rys. 1

  1. isstruct(A) zwraca prawdę jeśli A jest strukturą lub fałsz jeśli A strukturą nie jest. varargin zwraca ciąg 1xN, gdzie N to ilość inputów przesłanych do wykonywanej funkcji, lub zwraca pusty ciąg jeśli nie przesłano żadnego. Więc wraz z negacją ~ sprawdzamy tak naprawdę czy przesłano jakieś argumenty (o ile dobrze rozumiem, bo nigdzie znalazłem czegoś o varargin{end}, który przechowuje wartość ostaniej komórki ciągu). Jeśli nie to a, natomiast jeśli tak to b:
    a - przejście do warunku 2.
    b - sorted = 0

  2. isequal porównuje dwa lub więcej wartości/ciągi i jeśli są sobie równe to zwraca true lub fałsz jeżeli równe nie są. Tak więc sprawdzamy czy varargin{end} ma wartość ‘sorted’. Jeśli tak to a, jeśli nie to b:
    a - narginchk() opisany jest wyżej. Podany zakres jest od 2 do infinity, a więc muszą być conajmniej dwa inputy przesłane do funkcji, aby narginchk nie wyrzucił błędu. Reszta jak na załączonym obrazku rys. 1., gdzie N to ilość tych inputów
    b - wyrzucony zostaje błąd o podanej treści

sz0 = [] będzie później wykorzystywany do sprawdzenia czy wszystkie inputy mają taki sam rozmiar

NonEmptyInputs = false(N,1) oraz NonEmptyInputsN = 0 użyte będzie później do oceny stanu inputów

FN = cell(N,1) oraz VAL = cell(N,1) wykorzystywane do zbierania nazw oraz inputów

2.18 - Logi

writeToLogfile(text, Debug, textAreaHandle) - Opisane tu jest w jaki sposób zapisywane i wypisywane są logi

Wstęp

Opisane tu jest w jaki sposób zapisywane i wypisywane są logi.
Poniższy obrazek prezentuje cały kod pliku writeToLogfile.m

Działanie funkcji writeToLogfile(text, Debug, textAreaHandle)

Najpierw za pomocą funkcji fopen(filename,permission) otwierany jest plik o nazwie ErrorLog.txt podanej w pierwszym parametrze, a jako drugi parametr podawany jest rodzaj dostępu do pliku - a - oznaczający otworzenie lub utworzenie pliku do zapisu oraz dodanie tekstu na koniec pliku.

  1. Pierwsza funkcja warunkowa sprawdza czy plik został poprawnie otworzony. Jeśli fid jest równy -1, co oznacza, że funkcja fopen nie mogła otworzyć pliku, to fukncja error(msg) wyrzuca i wyświetla błąd o treści zdefiniowanej w parametrze msg

Funkcja fprintf(fileID,formatSpec,A1,...,An) i jej parametry:

parametr zmienna co przechowuje
fileID fid identyfikator wcześniej otworzonego pliku
formatSpec ‘%s: %s\n’ format tekstu - “A1: A2 nowa linia
A1 datestr(now, 0) aktualny czas w formacie ‘dd-mmm-yyyy HH:MM:SS’
A2 text tekst, który chcemy zapisać w pliku; parametr text funkcji writeToLogfile

Funkcja fclose zamyka plik.

  1. Druga funkcja warunkowa sprawdza czy nargin (ilość parametrów podanych przy wywołaniu funkcji) jest równe 3 oraz Debug (parametr funkcji writeToLogfile) jest true. Jeśli oba te warunki zostaną spełnione to w elemencie GUI textArea (ten w zakładce How-to) zostanie dopisana linia “loaded Track!" na jego końcu.

2.19 - Renderowanie Trasy

renderSelectedTrack.m - renderowanie wybranej trasy

Wstęp

renderSelectedTrack.m - renderowanie wybranej trasy

Tracks.Data

Tracks.Data to, jak widać na załączonym obrazku, matryca wypełniona pewnymi wartościami. Na niej opiera się cały plik renderSelectedTrack.m

Kolumna 1 - nazwa trasy
Kolumna 2 - długość trasy
Kolumna 3 - ???
Kolumna 4 - wartość określająca czy na trasie jest podział dyscyplin
Kolumna 5 - liczba okrążeń
Kolumna 6 - prędkość startowa
Kolumna 7 - nazwa pliku trasy

Deklaracja zmiennych

Pobierana jest nazwa pliku z nazwą toru z listy rozwijanej DropDown (tej z zakładki Simulation Setup, z sekcji Scenario, podpisanej jako Track).

Za pomocą funkcji load(filename,variables) ładowana jest wybrana trasa z podaną nazwą trasy.

Do x_Track_preview i y_Track_preview przypisywane są odpowiednio koordynaty x i y trasy przyjmując za jednostkę metry.

s_preview to przebieg długości trasy.

TrackName to nazwa trasy pobrana z wcześniej wspomnianej listy TrackDropDown (zakładka Simulation Setup => sekcja Scenario => Track).

Zmienna Co przechowuje
x_Track_preview koordynaty x trasy w [m]
y_Track_preview koordynaty y trasy w [m]
s_preview przebieg długości trasy
TrackName nazwa trasy pobrana z wcześniej wspomnianej listy TrackDropDown (zakładka Simulation Setup => sekcja Scenario => Track)
app.StartingSpeed prędkość startowa dla danej trasy, konwertując ją ze stringa na zmienną typu double
app.numOfLaps ilość okrążeń dla danej trasy, konwertując ją ze stringa na zmienną typu double

Funkcje warunkowe

  1. W pierwszym warunku po przekonwertowaniu zmiennej typu string na double sprawdzane jest czy na wybranej trasie są w ogóle dyscypliny. Jeśli tak to app.DisciplineDropDown zostaje włączony. W przeciwnym wypadku zostaje wyłączony.

  2. Następnie ustawiany jest motyw kolorystyczny w zależności czy zaznaczony został odpowiedni checkbox - app.DarkModeCheckBox.

  3. dopisać

  4. Czwarta funkcja warunkowa zawsze się wykona bo tak zostało zapisane w kodzie (DrawApexes ustawione na 1 czyli na true - ergo - warunek zawsze prawdziwy).
    Funkcja hold z drugim parametrem “on” ustawia podany w pierszym parametrze wykres na niepoddający się wymazywaniu istniejących linii przy rysowaniu nowych.
    Zmienna ApexIndizes to kurwa co to nwm pózniej dopisze bo psycha siada Funkcja scatter , gdzie:

    Parametr Czym jest
    app.UIAxes2 docelowy element
    x_Track_preview(ApexIndizes) objaśniona wcześniej zmienna
    y_Track_preview(ApexIndizes) objaśniona wcześniej zmienna
    20 pole powierzchni znaczników (w jednostce points)
    ‘r’ kolor - red (czerwony)
    ‘filled’ opcja do wypełnienia środka markerów

Przez app.UIAxes2.reset resetowany jest graficzny elementu app.UIAxes2.
Funkcja title(target,titletext,Name,Value) zatytułowuje wykres, gdzie:

Parametr Czym jest
target element docelowy (tutaj app.UIAzes2)
titletext nazwa toru podawana przez zmienną TrackName
Name nazwa atrybutu (tutaj rozmiar czcionki)
Value wartość atrybutu

Oraz ustawiana jest grubość jego linii i kolory zależne od wybranego motywu.

app.LengthLabel.Text = "Track Length: " + max(s_preview) + " m" ustawia tekst labela w kącie wykresu na pokazany tutaj tekst, gdzie max(s_preview) to maksymalna wartość z ciągu s_preview. W praktyce przedstawia on długość trasy.

2.20 - TirFiles

updateTirFiles.m - Wypełnienie wybranej listy rozwijanej dropDown plikami .tir

Wstęp

Funkcja zapełnia podany w parametrze dropDown element GUI typu dropDown listą plików o rozszerzeniu .tir z podanej lokalizacji i jej podfolderów.

Nazwa zmiennej Co przechowuje
folderPath ścieżka do plików .tir
fileList lista wszystkich plików o .tir w lokalizacji folderPath i jej podfolderach
fileNames lista nazw wszystkich plików z fileList
dropDown.Items itemy elementu dropDown podanego przy wywołaniu funkcji updateTirFiles wypełnione listą fileNames

W praktyce funkcja ta jest wykorzystywana jeden raz w pliku Suspension.mlapp i dotyczy tylko elementu app.TIRFileDropDown, w zakładce General, podpisanego jako TIR File.

3 - Regulamin Autonomiczny

Regulamin odnośnie budowy bolidu autonomicznego (FSG)

3.1 - Bolid autonomiczny - regulamin (ENG)

Streszczenie fragmentów FS Rules dotyczących bolidu autonomicznego

Bolid Autonomiczny

Znajdują się tutaj wszystkie fragmenty FS Rules które dotyczą bolidu autonomicznego w wersji cytowanej.

Wersja angielska (cytowana):

A 4.1.1 A university can register one CV team and one EV team which both can take part in the DC.

A 4.4 Autonomous System Responsible
A 4.4.1 To operate the AS, every participating team must appoint at least one ASR for the competition.
This person is responsible for all autonomous operations of the vehicle during the competition which includes any work on the autonomous system as well as racing and testing.
A 4.4.2 For vehicles with an electric drivetrain the ASR must fulfill A 4 .3 and therefore replaces the ESO. The team may register additional ESOs for accumulator inspection and work on Tracktive System (TS) only. The sum of registered ASRs and ESOs must not exceed four persons.
A 4.4.3 The ASR is the only person in the team who is allowed to declare the autonomous system safe, so that the vehicle may be operated in manual or autonomous mode.
A 4.4.4 The ASR must be a valid team member, which means that he/she must have student status, see A 4.2.6.
A 4.4.5 The ASR must accompany the vehicle whenever it is operated or moved around at the competition site.
A 4.4.6 If only one ASR is named by the team, this ASR may not be a driver.
A 4.4.7 The ASR must be properly qualified to handle the autonomous system and to understand and deal with problems and failures. As ASR Qualification (ASRQ), a bachelor degree in computer science, electrical engineering, mechatronics, automation engineering, robotics or similar (i.e. comparable study content or progress) is a sufficient qualification. The qualification certificate needs to be an official university document and contain information on completed courses.

A 5.6.2 [DC ONLY] At the end of the VSV, the vehicle must be stopped by an emergency brake maneuver (see T 15).
A 5.6.3 Autonomous Vehicle is required to have Autonomous System Status Indicator (ASSI)
A 5.6.3 [DC ONLY] In addition to the third person view, an onboard view and a visualization of the vehicle’s environment perception and path planning must be shown in split screen. All parts must be time synchronized.
[DC ONLY] Vehicle must drive without a driver
A 5.6.6 If a team fails only the [DC ONLY] part, it will only be de-registered from the DC.

A 6.3.2 All ASRs are required to attend the team briefing.

A 6.7.3 Vehicles must also have their autonomous system (see definition in T 14 .6) deactivated when being moved around the paddock. The ASR must ensure no unauthorized activation of the Autonomous System Master Switch (ASMS) following T 14.6.8.

T 1.4 Driving Mode Definitions

T 1.4.1 Manual Mode – A vehicle is in manual mode when driven by a human driver. In this case the ASMS must be off (AS deactivated).
T 1.4.2 Autonomous Mode – A vehicle is in autonomous mode when the AS is activated. When a vehicle is in autonomous mode, there must be no person inside the vehicle.

T 2.8.1 Steering systems using cables or belts for actuation are prohibited. This does not apply for autonomous steering actuators.

T 11 ELECTRICAL COMPONENTS

T 11.10 System Status Light
T 11.10.1 Any system status light(s), see T6.5 and T14.11 must meet the following requirements:

  • Black background
  • Rectangular, triangular or near round shape
  • Minimum illuminated surface of 15cm^2 with even luminous intensity
  • Clearly visible in very bright sunlight
  • If LED lights are used without a diffuser, they must not be more than 20mm apart
  • If a single line of LED lights is used, the minimum length is 150mm

T 14 AUTONOMOUS SYSTEM

T 14.1 Definitions
T 14.1.1 Each vehicle must implement a full AS according to T 14, to run in autonomous mode.
T 14.1.2 [CV ONLY] The following definitions apply to maintain the same wording as for Electric Vehicles:

  • Ready-to-drive (R2D) – Engine is running and a gear is engaged.
  • TS active – Engine is running but gearbox is in neutral (also assumed for TS not active).
  • TS activation button – The engine start button is the equivalent.
  • Accumulator Isolation Relay (AIR) - The fuel pump relay (see Figure 21) is the equivalent.

T 14.2 Teleoperated driving
T 14.2.1 Teleoperated driving is not allowed.

T 14.3 Data logger
T 14.3.1 The officials will provide a standardized data logger that must be installed during the competition. Further specifications for the data logger and required hardware and software interfaces can be found in the competition handbook.
T 14.3.2 The team needs to provide two sets of signals to the data logger:

  • Basic set of signals as defined in the competition handbook
  • Vehicle-individual set of signals that is monitored by the ASB to ensure redundancy and fault detection
  • [CV Only] The mounting of data logger must be sealed during technical inspection.

T 14.4 Remote Emergency System
T 14.4.1 Every vehicle must be equipped with a standard RES specified in the competition handbook.
The system consists of two parts, the remote control and the vehicle module.
T 14.4.2 The RES must be purchased by the team.
T 14.4.3 The RES has two functions:

  • When the remote emergency stop button is pressed, it must open the SDC defined in T 14.5.
  • When the “Go” button is pressed, the preselected autonomous mission is started.

T 14.4.4 The RES vehicle module must be directly integrated in the vehicle’s SDC with one of its relays hard-wired in series to the shutdown buttons.
T 14.4.5 The RES relay, which is integrated into the SDC, may be bypassed by a normally closed relays, when driving manually. The relay must:

  • be directly supplied by the ASMS, see T 14.7
  • have a safety certified forcibly guided or a mirrored normally open contact which is directly connected in series to the ASMS

T 14.4.6 The antenna of the RES must be mounted unobstructed and without interfering parts in proximity (other antennas, etc.).

T 14.5 Shutdown Circuit
T 14.5.1 The SDC may only be closed by the AS, if the following conditions are fulfilled:

  • Manual Driving: Manual Mission is selected, the AS has checked that ASB is deactivated (No autonomous brake actuation possible).
  • Autonomous Driving: Autonomous Mission is selected, ASMS is switched on and sufficient brake pressure is built up (brakes are closed).

T 14.6 Signals
T 14.6.1 Any signal of the AS is a SCS. If failures lead to loss of environment perception and/or localization, the system must react accordingly.

T 14.7 Autonomous System Master Switch
T 14.7.1 Each vehicle must be equipped with an ASMS, according to T 11.2.
T 14.7.2 The ASMS must be mounted in the middle of a completely blue circular area of ≥50 mm diameter placed on a high contrast background.
T 14.7.3 The ASMS must be marked with “AS”.
T 14.7.4 The power supply of the steering and braking actuators must be switched by

  • LVMS
  • ASMS

Other than stated in T 11.2.1, non-programmable logic may be used as part of the ASMS.
T 14.7.5 When the ASMS is in “Off” position, the following must be fulfilled:

  • No steering, braking and propulsion actuation can be performed by request of the autonomous system.
  • The sensors and the processing units can stay operational.
  • The vehicle must be able to be pushed as specified in A 6.7.
  • It must be possible to operate the vehicle manually as a normal CV or EV.

T 14.7.6 It is strictly forbidden to switch the ASMS to the “On” position if a person is inside the vehicle.
T 14.7.7 After switching the ASMS to the “On” position, the vehicle must not start moving, until R2D is entered (Figure 17).
T 14.7.8 The ASMS must be fitted with a “lockout/tagout” capability to prevent accidental activation of the AS. The ASR must ensure that the ASMS is locked in the off position whenever the vehicle is outside the dynamic area or driven in manual mode.

T 14.8 Steering Actuation
T 14.8.1 Steering system actuation (movement) must only happen if the vehicle is R2D.
T 14.8.2 The steering system may remain active during an emergency brake maneuver while the vehicle is in movement.
T 14.8.3 Manual steering must be possible without manual release steps (e.g. operating manual valves / (dis-) connecting mechanical elements) while the ASMS is switched “Off”.

T 14.9 Actuator Decoupling
T 14.9.1 It is not allowed to remove any parts of the autonomous system for dynamic events.
T 14.9.2 The actuators may be disconnected for manual driving if:

  • no parts including bolts, clips, etc. are removed for disconnection i.e. they must never loose the physical contact to the disconnection mechanism.
  • the disconnection mechanism cannot block manual operation in any position.
  • the disconnection mechanism is securely locked in both positions.

T 14.10 Autonomous System Status Definitions
T 14.10.1 The Emergency Brake System (EBS) is considered to be “activated”, if the power supply path defined in T 15 .2.2 is cut after passing the initial checkup sequence ( T 15 .3.1). Brakes may only be released after performing manual steps.
T 14.10.2 The status of the AS must be determined according to the flowchart below.


T 14.10.3 R2D may only be activated by the “Go” signal from the RES, after the system has remained in “AS Ready” for at least 5 s.
T 14.10.4 Performing manual steps, other than activating the TS, at the vehicle while the ASMS is switched “On” is prohibited.

T 14.11 Autonomous System Status Indicators
T 14.11.1 The vehicle must include three ASSIs that must indicate the status of the AS (as defined in T 14.10) correlating to illumination as shown:

AS Off AS Ready AS Driving AS Emergency AS Finished
off yellow continuous yellow flashing blue flashing blue continuous

The ASSIs may not perform any other functions.
T 14.11.2 One ASSI must be located on each side of the vehicle behind the driver’s compartment, in a region 160 mm below the top of the main hoop and 600 mm above the ground. The third ASSI must be located at the rear of the vehicle, on the vehicle centerline, in a region 160 mm below the top of the main hoop and 100 mm above the brake light.
T 14.11.3 At least one ASSI must be visible from any angle of the vehicle from a point 1.60m vertically from ground level, within 3m horizontal radius from the top of the main hoop.
T 14.11.4 Each ASSI must meet the requirements according to T 11.10.
T 14.11.5 The status “AS Emergency” has to be indicated by an intermittent sound with the following parameters:

  • on-/off-frequency: 1 Hz to 5 Hz
  • duty cycle 50 %
  • sound level between 80 dBA and 90 dBA, fast weighting in a radius of 2 m around the vehicle.
  • duration between 8 s and 10 s after entering “AS Emergency”

T 14.12 Autonomous Missions
T 14.12.1 The AS must at least implement the following missions:

  • Acceleration
  • Skidpad
  • [DC ONLY] Autocross
  • [DC ONLY] Trackdrive
  • EBS test
  • Inspection
  • Manual driving

T 14.12.2 The inspection mission is defined by slowly spinning the drivetrain and actuating the steering system with a sine wave while the vehicle is jacked up and all wheels are removed. After 25 s to 30 s the AS must transition to “AS Finished”.
T 14.12.3 It must be possible to select any mission without the use of an external device.
T 14.12.4 The selected mission must be indicated by the Autonomous Mission Indicator (AMI).
T 14.12.5 The AMI must be easily readable and can either be part of the dashboard or located next to the ASMS. If an e-ink display is used, it must be visible that the shown mission is up-to-date.
AMI is considered SCS!

T 14.13 Autonomous System Form
T 14.13.1 Prior to the competition, all teams must submit a clearly structured documentation of their entire AS (including ASB) called ASF.

T 15 AUTONOMOUS SYSTEM BRAKE

T 15.1 Technical Requirements
T 15.1.1 To run in autonomous mode, the vehicle must be equipped with an ASB that features an EBS as part of it (see T 15.2).
T 15.1.2 All parts of the ASB must be located within the rollover protection envelope, see T 1.1.16.
T 15.1.3 The tractive system is not considered to be a brake system.
T 15.1.4 Manual braking must always be possible. In case of manual and autonomous braking simultaneously, always the highest of both pressures must be applied to the brakes.
T 15.1.5 Master brake cylinders must not be connected in series.
T 15.1.6 The ASB may be part of the hydraulic brake system. For all components inside the vehicles brake circuit T 6 is applied. On all remaining pneumatic and hydraulic components T 9 applies.
T 15.1.7 The ASB must be designed so that it can be easily deactivated by a maximum of two deactivation points.
T 15.1.8 All deactivation points of the ASB must:

  • work without the aid of electrical power
  • be in proximity to each other
  • either be mounted in proximity to the ASMS or on the top side of the vehicle between front bulkhead and front hoop close to the vehicles center line
  • be operable by maximum two simple push/pull and/or turning actions, the order and direction of these actions must be shown next to the deactivation points.
  • be marked with “Brake release”
  • have a red handle

T 15.1.9 The use of push-in fittings is prohibited in function critical pneumatic circuits of the ASB and any other system, which uses the same energy storage without proper decoupling.

T 15.2 Emergency Brake System
T 15.2.1 The EBS must only use passive systems with mechanical energy storage. Electrical power- loss at EBS must lead to a direct emergency brake maneuver with the performance specified in T 15.4.
T 15.2.2 The EBS must be supplied by LVMS, ASMS, RES and a relay which is supplied by the SDC (parallel to the AIRs, but must not be delayed).

T 15.3 Functional Safety
T 15.3.1 An initial check has to be performed to ensure that ASB is able to build up brake pressure as expected, before AS transitions to “AS Ready”.
T 15.3.2 After the initial check the ASB and its SCS must be continuously monitored for failures.
T 15.3.3 The vehicle must automatically transition to the safe state, if:

  • the functionality according to T 15.2.1 cannot be ensured.
  • an (additional) single point of failure would lead to total loss of brake capability.

T 15.3.4 The safe state is the vehicle at a standstill, brakes engaged to prevent the vehicle from rolling, and an open SDC.
T 15.3.5 To get to the safe state, the vehicle must perform an autonomous brake maneuver described in section T 15.4 and IN 11.2.

T 15.4 Emergency Brake System Performance
T 15.4.1 The system reaction time (the time between opening of the SDC and the start of the deceleration) must not exceed 200 ms.
T 15.4.2 The average deceleration must be greater than 10 m/s2 under dry track conditions.
T 15.4.3 In case of a single failure the ASB should be designed to achieve at least half of the performance specified in T 15.4.2.
T 15.4.4 Whilst decelerating, the vehicle must remain in a stable driving condition.

CV 1.2.2 For autonomous operation, the vehicle must be equipped with an additional engine start button next to the LVMS, see T 11.3, that can be easily actuated from outside the vehicle.
Using the external engine start button, the engine may only start if

  • the ASMS (see T 14.7) is switched on and
  • the gearbox is in neutral.

CV 1.2.4 The AS must not be able to (re-)start the engine.

CV 1.5.1 CV 1.5 (Mechanical Throttle Actuation) can only be used if no AS is used.

IN 1.2.1 Each vehicle must pass all parts of technical inspection except Autonomous System Inspection and EBS test before it may participate in any dynamic event.
IN 1.2.2 Each vehicle must pass Autonomous System Inspection and EBS Test before it may participate in any driverless dynamic event.

IN 1.5.1 After the technical inspection it is prohibited to adjust AS sensors

IN 6.1 Autonomous System Inspection Required Items

IN 6.1.1 The following items are required:

  • One ASR
  • The vehicle (in fully assembled, ready-to-race condition including mounted data logger (see T 14.3))
  • Data sheets for all perception sensors
  • Documents which proof that all perception sensors meet local legislation
  • RES remote control
  • ASF
  • Tools needed for the (dis)assembly of parts for autonomous system inspection
  • Print-outs of rule questions (if applicable)

3.2 - Bolid autonomiczny - regulamin (PL)

Streszczenie fragmentów FS Rules dotyczących bolidu autonomicznego w tłumaczeniu na język polski. Tłumaczenie wykonano tylko w celu uzupełnienia informacji, zaleca się korzystanie z oryginału w wersji angielskiej.

Bolid Autonomiczny

Znajdują się tutaj wszystkie fragmenty FS Rules które dotyczą bolidu autonomicznego we własnym przekładzie na język polski. Wszystkie użyte skróty definicji pochodzą z wersji angielskiej FS Rules 2024.

Wersja Polska (tłumaczenie własne)

A 4.1.1 Uczelnia może zarejestrować na zawody jedną drużynę z bolidem o silniku spalinowym i jedną drużynę z bolidem o silniku elektrycznym. Obydwie drużyny mogą brać udział w konkurencjach DC (pojazdy autonomiczne/bez kierowców)

A 4.4 Osoba odpowiedzialna za System Autonomiczny (ASR)
A 4.4.1 Celem wdrożenia do działania systemu autonimicznego, każda drużyna musi wybrać (minimum) jedną osobę odpowiedzialną za system autonomiczny. Osoba ta odpowiedzialna jest za wszystkie działania bolidu mające związek z systemem autonomicznym podczas zawodów. W skład tych działań wchodzi praca nad bolidem/systemem autonomicznym, jego testami, a także jego udziałem w poszczególnych konkurencjach.
A 4.4.2 W przpadku bolidów o napędzie elektrycznym Osoba odpowiedzialna za system autonomiczny (ASR) spełnia wszystkie obowiązki wymienione w punkcie 4.3 Regulacji Formuły Student na rok 2024, tym samym pełni też rolę osoby odpowiedzialnej za systemy elektryczne bolidu. Drużyna może powołać dodatkowe osoby do roli osób odpowiedzialnych za baterie/akumulatory i system trakcyjny. Suma zarejestrowanych ASR’ów i ESO (Osób odpowiedzialnych za systemy elektryczne) nie może przekraczać 4 osób.
A 4.4.3 Osoba odpowiedzialna za system autonomiczny jest jedyną w zespole, która może zadeklarować bolid wyposażony w system autonomiczny jako bezpieczny, umożliwiając tym samym przełączanie pojazdu między trybem jazdy manualnym i autonomicznym.
A 4.4.4 Osoba odpowiedzialna za system autonomiczny musi być pełnoprawnym członkiem zespołu. Więcej o kryteriach, jakie powinien spełniać członek zespołu można znaleźć w podpunkcie A 4.2.6
A 4.4.5 Osoba odpowiedzialna za system autonomiczny musi być obecna w pobliżu bolidu zawsze, gdy jest on w użyciu, jest transportowany na terenie zawodów.
A 4.4.6 Jeśli zespół wybrał tylko jedną Osobę odpowiedzialną za system autonomiczny, to osoba ta nie może być kierowcą.
A 4.4.7 Osoba odpowiedzialna za system autonomiczny musi odznaczać się odpowiednią wiedzą i umiejętnościami, by móc operować systemem autonomicznym, rozumieć jego działanie i skutecznie radzić sobie z jego naprawami, usterkami i testami. Kwalifikacja ASR, licencjat z: informatyki, elektryki, mechatroniki, automatyki, robotyki lub podobnych kierunków są wystarczające. Dokument potwierdzający kwalifikacje musi być oficjalnym dokumentem wydanym przez uczelnię i zawierać dokładne informacje o posiadanych kwalifikacjach.

A 5.6.2 [Tylko DC] Pod koniec VSV, samochód musi być przeprowadzić procedurę hamowania awaryjnego.
A 5.6.3 Pojazd autonomiczny musi posiadać ASSI (Sygnalizator Statusu Systemu Autonomicznego)
A 5.6.3 [Tylko DC] Oprócz widoku z trzeciej osoby, widok na kokpit i wizualizacja widoczności systemu autonomicznego i systema planowania trasy bolidu muszą być ujęte na podzielonym ekranie. Wszystkie te elementy muszą być zsynchronizowane w czasie.
[Tylko DC] W trybie autonomicznym pojazd musi poruszać się bez udziału kierowcy.
A 5.6.6 Jeśli drużynia odpadnie tylko z części zawodów dla pojazdów autonomicznych, to jest wykluczona tylko z ów części zawodów i nie ma to wpływu na pozostałe kategorie zawodów.

A 6.3.2 Wszystkie osoby odpowiedzialne za system autonomiczny muszą być obecne podczas spotkania drużynowego.

A 6.7.4 System autonomiczny bolidu musi być wyłączony (więcej w T 14.6), gdy jest transportowany na terenie padoku. Osoby odpowiedzialne za system autonomiczny muszą dopilnować, by nie doszło do nieautoryzowanej aktywacji głównego przełącznika systemu autonomicznego (ASMS), o czym mówi więcej podpunkt T 14.6.8 regulacji.

T 1.4 Definicje trybu jazdy

T 1.4.1 Tryb Manualny - pojazd znajduje się w trybie manualnym, gdy jest prowadzony przez człowieka. W tym wypadku w.w. ASMS musi być wyłączony.
T 1.4.2 Tryb Autonomiczny - pojazd znajduje się w trybie autonomicznym, gdy aktywny jest system autonomiczny. W tym trybie nikt nie może znajdować się wewnątrz pojazdu.

T 2.7.1 Systemy wspomagania prowadzenia pojazdu w formie linek, przewodów, pasków itp. do manipulowania przełącznikami w kokpicie są zabronione. Wyjątkiem jest, jeśli są one używane tylko i wyłącznie przez system autonomiczny.

T 11 Komponenty Elektryczne

T 11.10 Lampka stanu systemu (System Status Light)
T 11.10.1 Każda lampka sygnalizująca stan systemu elektrycznego(jak opisano w T 6.5 i T 14.11) musi spełnić następujące wymagania:

  • Czarne tło
  • Prostokątny, trójkątny lub okrągły kształt
  • Równomiernie podświetlona powierzchnia o polu minimum 15cm^2
  • Musi być dobrze widoczne w jasnym świetle słonecznym
  • Jeśli uzyto diod LED, to odległość między nimi nie może przekraczać 20mm
  • Jeśli użyto pojedynczego paska LED, to musi on mieć minimum 150mm długości

T 14 System Autonomiczny (AS)

T 14.1 Definicje
T 14.1.1 Każdy pojazd musi zaimplementować kompletny system autonomiczny, jak opisano w punkcie T14 i musi być prowadzony w trybie autonomicznym.
T 14.1.2 [Tylko CV] Poniższe definicje stosowane są celem utrzymania zgodności z sekcją o bolidach elektrycznych:

  • Gotowość do jazdy - Silnik jest włączony i załączony jest bieg.
  • System trakcyjny aktywny - Silnik jest łączony i bolid jest na biegu jałowym (także gdy nie jest aktywny system trakcyjny (?))
  • Przekaźnik izolacji akumulatora (PIA) - Przekaźnik pompy paliwa jest ekwiwalentem.

T 14.2 Zdalne sterowanie bolidem
T 14.2.1 Zdalne sterowanie bolidem jest praktyką niedozwoloną

T 14.3 Zbieranie danych
T 14.3.1 Organizatorzy zawodów dostarczą ustandaryzowane urządzenie do zbierania danych, który musi być zamontowany w bolidzie na czas zawodów. Dalsze specyfikacje urządzenia i wymagany przez niego osprzęt i oprogramowanie można znaleźć w handbook’u.
T 14.3.2 Zespół musi dostarczyć dwa zestawy sygnałów do urządzenia zbierającego dane:

  • Podstawowy zestaw sygnałów opisany w handbook’u
  • Zestaw sygnałów charakterystyczny dla specyfiki danego bolidu monitorowany przez ASB (Autonomiczny system hamowania) celem zapewnienia nadmiarowości i wykrywania błędów.
  • [Tylko CV] Mocowanie urządzenia zbierającego dane musi być zaplombowane podczas inspekcji technicznej

T 14.4 Zdalny system awaryjny (RES)
T 14.4.1 Każdy bolid musi zostać wyposażony w ustandaryzowany Zdalny System Awaryjny, któy dokładnie został opisany w handbooku.
T 14.4.2 RES musi zostać zakupiony przez zespół.
T 14.4.3 RES posiada dwie funkcje:

  • Gdy wciśnięty jest przycisk zatrzymania awaryjnego, musi aktywować awaryjny obwód opisany w podpunkcie T 14.5.
  • Gdy przycisk jazdy jest wciśnięty aktywowany jest przygotowany wcześniej protokół/proces jazdy.

T 14.4.4 Moduł RES pojazdu musi być bezpośrednio zintegrowany z jednym z przełączników obwodu awaryjnego
T 14.4.5 Przełącznik RES, który jest zintegrowany z SDC (Obwód przerywający) może być ominięty przez zwykle aktywne przełączniki, gdy bolid znajduje się w trybie jazdy manualnej. Przełącznik musi:

  • być ciągle w połączniu z ASMS (Główny przełącznik trybu autonomicznego), więcej w T 14.7
  • posiadać certyfikowany pod względem bezpieczeństwa wymuszony lub zwykle aktywne połączenie wpięte bezpośrednio i szeregowo z ASMS.

T 14.4.6 Antena modułu RES musi być zamontowana w sposób niekolidujący z innymi elementami pojazdu, innymi modułami bądź antenami.

T 14.5 Obwód przerywający (SDC) T 14.5.1 Obwód przerywający może zostać zamknięty wyłącznie przez system autonomiczny, jeśli spełnione są następujące warunki:

  • W trybie manualnym - Wybrane jest zadanie jazdy manualnej, systemy jazdy autonomicznej i hamowania autonomicznego są wyłączone.
  • W trybie autonomicznym - Wybrane jest zadanie jazdy autonomicznej, główny przełącznik jazdy autonomicznej jest w pozycji aktywnej i system hamowania autonomicznego jest aktywny i gotowy do działania.

T 14.6 Sygnały
T 14.6.1 Każdy sygnał wysłany przez system autonomiczny jest sygnałem krytycznym (czyli szczególnie ważnym). Jeśli błędy w działaniu bądź intepretacji sygnału mogą prowadzić do zaburzenia percepcji otoczenia systemu autonomicznego, misintepretacji sygnałów bądź zaburzeń autonimicznej jazdy, system musi odpowiednio zareagować.

T 14.7 Główny przełącznik systemu autonomicznego (ASMS)
T 14.7.1 Każdy pojazd musi być wyposażony w główny przełącznik trybu autonomicznego.
T 14.7.2 Główny przełącznik systemu autonomicznego musi być zamontoway w środku niebieskiej okrągłej strefy o średnicy ≥ 50 mm, umiejscowionej na mocno kontrastującym tle.
T 14.7.3 ASMS musi być oznaczony jako “AS”.
T 14.7.4 Zasilanie układu prowadzenia i aktywacja hamulców musi być przełączana/zarządzana przez:

  • LVMS - Low Voltage Master Switch (Główny przełącznik niskiego napięcia)
  • ASMS

Oprócz elementów ujętych w T 11.2.1 dozwolone jest użycie nieprogramowalnych układów jako elementów ASMS.
T 14.7.5 Gdy ASMS jest w pozycji wyłączonej, spełnione muszą być następujące warunki:

  • System autonomiczny nie może wykonać procedury sterowania pojazdem, hamowania ani aktywacji napędu.
  • Czujniki i sensory połączone z systemem autonomicznym mogą pozostać aktywne.
  • Pojazd musi być możliwy do przemieszczenia wedle opisu w podpunkcie A 6.7.
  • Pojazd musi być możliwy do prowadzenia w trybie manualnym tak jak zwykły pojazd kategorii CV lub EV.

T 14.7.6 Surowo zabroniona jest aktywacja ASMS gdy wewnątrz pojazdu znajduje się człowiek.
T 14.7.7 Gdy ASMS zostanie aktywowany pojazd nie może się przemieścić zanimnie wejdzie w stan R2D (czyli dopóki nie da sygnału gotowości do jazdy)
T 14.7.8 ASMS musi zostać wyposażony w zabezpieczenie chroniące przed przypadkową aktywacją. Osoba odpowiedzialna za system autonomiczny jest odpowiedzialna za kontrolowanie poprawnego użycia ASMS i zapewnienie, że przełącznik jest zablokowany w pozycji wyłączonej w czasie, gdy pojazd znajduje się poza strefą dynamiczną (czyli gdy się nie ściga) oraz gdy jest prowadzony w trybie manualnym.

T 14.8 Aktywacja układu prowadzenia
T 14.8.1 Aktywacja układu prowadzenia i jego użycie może nastąpić wyłącznie, gdy pojazd jest gotowy do jazdy.
T 14.8.2 Układ prowadzenia może być aktywny podczas procedury hamowania awaryjnego w czasie, gdy pojazd jest w ruchu.
T 14.8.3 Prowadzenie pojazdu w trybie manualnym musi być możliwe bez dodatkowych manualnych czynności (jak ręczne przełączanie/przepinanie elementów pojazdu) w czasie, gdy ASMS jest w pozycji wyłączonej.

T 14.9 Odłączenie elementów
T 14.9.1 Niedozwolone jest odłączanie żadnych części systemu autonomicznedgo w czasie trwania konkurencji dynamicznych.
T 14.9.2 Siłowniki/aktywatory mogą być odłączone celem przygotowania do jazdy manualnej, jeśli:

  • Żadne elementy (w tym śruby i innego rodzaju elementy łączące) nie mogą być usunięte z pojazdu, to jest nie mogą utracić fizycznego kontaktu z mechanizmem odłączającym.
  • Mechanizm odłączający nie może blokować czynności manualnych w żadnej pozycji czy płaszczyźnie.
  • Mechanizm odłączający musi być zabezpieczony w każdej pozycji.

T 14.10 Definicje dotyczące statusu systemu autonomicznego - (ASSI)
T 14.10.1 System hamowania awaryjnego (EBS) uznawany jest za aktywny, gdy jego połączenie ze źródłem zasilania opisane w T 15.2.2 jest rozłączone po dokonaniu wstępnej sekwencji kontrolnej opisanej w T 15.3.1. Hamulce mogą być zwolnione po przeprowadzeniu kroków manualnych.
T 14.10.2 Status systemu autonomicznego musi być określany na podstawie schematu poniżej:


T 14.10.3 Status R2D (czyli gotowości do jazdy) może być aktywowany jedynie przez sygnał gotowości z modułu RES, gdy system trwał w trybie gotowości systemu autonomicznego (AS Ready) przez minimum 5 sekund.
T 14.10.4 Przeprowadzając czynności manualne inne niż aktywacja systemu trakcyjnego (TS) w pojeździe podczas, gdy główny przełącznik systemu autonomicznego jest w pozycji aktywnej są zabronione.

T 14.11 Wskaźniki/sygnalizatory statusu systemu autonomicznego
T 14.11.1 Pojazd musi zostać wyposażony w trzy ASSI (wskaźniki statusu systemu autonomicznego, lub inaczej sygnalizatory), które muszą informować o aktualnym statusie systemu autonomicznego. Sygnały muszą być zgodne z poniższą tabelką:

SA Wyłączony SA Gotowy SA w ruchu SA w stanie awaryjnym SA zakończył działanie
Brak Żółty ciągły Żółty przerywany Niebieski przerywany Niebieski ciągły

SA - System autonomiczny

ASSI nie mogą pełnić innych funkcji.
T 14.11.2 Dwa ASSI umiejscowione muszą być po bokach pojazdu za miejscem kierowcy, po jednym po każdej stronie. Dokładne umiejscowienie określono na obszar 160 mm pod szczytem obręczy głównej (main hoop) i 600 mm nad ziemią. Trzeci ASSI musi znajdować się z tyłu pojazdu w osi centralnej pojazdu w obszarze 160 mm pod szczytem obręczy głównej i 100 mm nad światłem hamowania.
T 14.11.3 Minimum jeden ASSI musi być widoczny pod każdym kątem powyżej 1.60m nad ziemią dookoła bolidu, w promieniu 3m od najwyższego punktu main hoop’a (czubka jego ramy)
T 14.11.4 Każdy ASSI musi spełniać wymogi opisane w T 11.10
T 14.11.5 Status awaryjne systemu autonomicznego (AS Emergency) musi być sygnalizowany sygnałem dźwiękowym o następujących cechach:

  • częstotliwość między 1 a 5Hz
  • cykl pracy 50%
  • głośność między 80 a 90 dBA mierzona w odległości 3m od bolidu
  • czas trwania między 8 a 10s po wejściu w stan awaryjny

T 14.12 Misje/Zadania Autonomiczne
T 14.12.1 System Autonomiczny musi mieć zaimplementowane minimalnie poniższe zadania/konkurencje:

  • Acceleration (Przyspieszanie)
  • Skidpad
  • [DC ONLY(Tylko dla autonomików)] Autocross
  • [DC ONLY(Tylko dla autonomików)] Trackdrive
  • Test hamowania awaryjnego (EBS test)
  • Inspekcja
  • Tryb jazdy manualnej

T 14.12.2 Zadanie Inspekcji oznacza wejście silnika na wolne obroty i aktywowanie układu sterowniczego za pomocą sygnału sinusoidalnego. W tym czasie pojazd znajduje sie na podnośniku i nie posiada założonych kół. Po 25-30 sekundach pojazd musi przejść w tryb “AS Finished”, co oznacza zakończenie inspekcji.
T 14.12.3 Możliwe musi być wybranie dowolnej misji/zadania bez konieczności używania dodatkowych urządzeń zewnętrznych.
T 14.12.4 Rodzaj wybranej misji/zadania musi być sygnalizowany przez AMI (Autonomous Mission Indicator - Sygnalizator misji autonomicznej).
T 14.12.5 AMI musi być łatwy do odczytania, może być częścią wyświetlacza w bolidzie bądź może być umiejscowiony w pobliżu ASMS (Autonomous System Master Switch - Główny przełącznik systemu autonomicznego). Jeśli jako wyświetlacz użyto elektronicznego tuszu (e-ink), to musi znajdować się na nim informacja zapewniająca, że stan systemu jest aktualny. AMI uznawany jest jako SCS (System Critical Sygnał - Sygnał krytyczny).

T 14.13 Formularz Systemu Autonomicznego (ASF)
T 14.13.1 Przed rozpoczęciem zawodów, wszystkie zespoły muszą zaprezentować jasno i dokładnie zaprojektowaną dokumentację techniczną całego Systemu Autonomicznego, także zawierającą w sobie ASB (informacje na temat autonomicznego hamowania), którą nazwano ASF, czyli Formularz Systemu Autonomicznego.

T 15 System Hamowania Autonomicznego (ASB)

T 15.1 Wymogi techniczne
T 15.1.1 By uruchomić i operować w trybie autonomicznym, pojazd musi zostać wyposażony w system hamowania autonomicznego, którego elementem składowym także jest system hamowania awaryjnego opisany w T 15.2.
T 15.1.2 Wszystkie elementy ASB muszą być zlokalizowane w pobliżu ochrony przed przetoczeniem bolidu (Rollover Protection Envelope), jak opisano w T 1.1.16.
T 15.1.3 System trakcyjny NIE jest uznawany jako system hamowania/układ hamulcowy.
T 15.1.4 Hamowanie manualne musi zawsze być możliwe. W przypadku jednoczesnego hamowania manualnego i autonomicznego, zawsze do układu musi być dostarczane maksymalne możliwe ciśnienie.
T 15.1.5 Główne zbiorniki hamulcowe nie mogą być połączone szeregowo.
T 15.1.6 ASB (Autonomiczny System Hamowania) może być częścią hydraulicznego układu hamulcowego. Dla wszystkich elementów układu hamulcowego stosuje się obwód opisany w T 6. Do wszystkich pozostałych pneumatycznych i hydraulicznych komponentów stosuje się punkt T 9.
T 15.1.7 ASB musi być tak zaprojektowany, aby możliwe było jest łatwe odłączenie w maksymalnie dwóch punktach deaktywacji.
T 15.1.8 Wszystkie punkty deaktywacji ASB muszą:

  • pracować bez użycia elektryczności
  • być w pobliżu siebie
  • muszą być zamontowane w pobliżu ASMS lub na górnej powierzchni pojazdu między przednią przegrodą a główną obręczą w pobliżu osi centralnej bolidu
  • być sterowane za pomocą mksumalnie dwóch odpychających/przyciągających czynności. Kierunek i zwrot czynności musi być w pobliżu punktów deaktywacyjnych
  • być opisane jako “Brake Release”, czyli “Zwolnienie Hamulca”
  • mieć czerwony uchwyt/dźwignię

T 15.1.9 Użycie mocowań wciskowych jest zabronione w przypadku krytycznych układów pneumatycznych ASB oraz każdego innego układu/systemu korzystającego z tych samych źródeł energii niewyposażonych w poprawny rozłącznik.

T 15.2 System Hamowania Awaryjnego (EBS)
T 15.2.1 EBS musi używać jedynie ukadów/systemów pasywnych z mechanicznym zbiornikiem energii. Utrata energii elektrycznej z układu EBS musi prowadzić do natychmiastowego rozpoczęcia hamowania o specyfikacji określonej w punkcie T 15.4.
T 15.2.2 EBS musi być zintegrowany z LVMS, ASMS i RES, a także przełącznikiem zintegrowanym z SDC (równolegle z AIR (przełącznikiem izolaci akumulatora) bez opóźnień)

T 15.3 Bezpieczeństwo
T 15.3.1 Wstępna kontrola musi być przeaprowadzona celem potwierdzenia, że ASB jest w stanie wyprodukować wymaganie ciśnienie w układzie hamulcowym zanim AS (system autonomiczny) zostanie przełączony w tryb gotowości.
T 15.3.2 Po przeprowadzeniu kontroli wstępnej systemy ASB i SCS muszą być stale monitorowane pod kątem błędów i usterek.
T 15.3.3 Pojazd musi samodzielnie przełączyć się w stan bezpieczny, jeśli:

  • nie można spełnić wymogów opisanych w T 15.2.1
  • jeśli którykolwiek błąd w działaniu może prowadzić do utraty kontroli lub utracenia możliwości hamowania

T 15.3.4 Stan bezpieczny określa się jako stan, w którym pojazd jest w spoczynku (nie porusza się), a jego hamulce są zaciśnięte celem zapobiegnięcia jego niekontrolowanemu przemieszczeniu. Ponadto SDC (Obwód odłączający) musi być otwarty T 15.3.5 Aby wejść w stan bezpieczny pojazd musi wykonać manewr hamowania opisany w punktach T 15.4 oraz IN 11.2

T 15.4 Specyfikacja Awaryjnego Systemu Hamowania (EBSP)
T 15.4.1 Czas reakcji układu/systemu (czas między aktywacją SDC a rozpoczęciem hamowania) nie może przekroczyć 200 ms
T 15.4.2 Średnia prędkość hamowania musi być wyższa niż 10 m/s2 w warunkach suchej nawierzchni
T 15.4.3 W przypadku pojedynczej awarii ASB powinien zostać przeprojektowany, celem spełnienia minimum połowy specyfikacji opisanej w T 15.4.2
T 15.4.4 Podczas hamowania pojazd musi pozostać stabilny

CV 1.2.4 System autonomiczny nie może być wstanie (ponownie) uruchomić silnika

CV 1.5.1 Mechaniczna aktywacja hamulca może zostać użyta tylko, gdy tryb autonomiczny jest wyłączony

IN 1.2.1 Każdy pojazd musi pomyślnie przejść wszystkie elementy inspekcji technicznej oprócz inspekcji systemu autonomicznego, by móc zostać dopuszczonym do konkurencji dynamicznych go nie wymagających
IN 1.2.2 Każdy pojazd przed przystąpieniem do konkurencji dynamicznych dla pojazdów autonomicznych musi pomyślnie przejść inspekcję systemu autonomicznego

IN 1.5.1 Po zakończeniu inspekcji technicznej zabronione jest korygowanie sensorów systemu autonomicznego

IN 6.1 Elementy wymagane podczas inspekcji technicznej systemu autonomicznego

IN 6.1.1 Podczas inspekcji systemu autonomicznego wymaga się:

  • Jednej osoby odpowiedzialnej za system autonomiczny
  • W pełni gotowego pojazdu wyposażonego w system autonomiczny
  • Dokumentacji wszystkich sensorów uzytych w pojeździe
  • Dokumentów potwierdzających legislacje wszystkich użytych sensorów percepcji
  • Zdalnego sterowania RES (Zdalnym systemem awaryjnym)
  • ASF (Formularza systemu autonomicznego)
  • Narzędzi wymaganych do (roz)montowania części systemu autonomicznego
  • (W niektórych przypadkach) wydruków pytań z regulaminu