HW2: Assignment 2 added

This commit is contained in:
Christos Choutouridis 2025-10-26 00:28:24 +03:00
parent de85e9cf10
commit 5e17867857
20 changed files with 522 additions and 2 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "Work 1/report/AUThReport"] [submodule "Work 1/report/AUThReport"]
path = Work 1/report/AUThReport path = Work 1/report/AUThReport
url = ssh://git@git.hoo2.net:222/hoo2/AUThReport.git url = ssh://git@git.hoo2.net:222/hoo2/AUThReport.git
[submodule "Work 2/report/AUThReport"]
path = Work 2/report/AUThReport
url = ssh://git@git.hoo2.net:222/hoo2/AUThReport.git

Binary file not shown.

View File

@ -48,7 +48,7 @@
%\CoAuthorMail{xxx@ece.auth.gr} %\CoAuthorMail{xxx@ece.auth.gr}
\DocTitle{Εργασία 1} \DocTitle{Εργασία 1}
\DocSubTitle{Έλεγχος γωνίας προσανατολισμού δορυφόρου με ασαφείς ελεγκτές} \DocSubTitle{Έλεγχος γωνίας προσανατολισμού δορυφόρου - Σειρά 15}
\Department{Τμήμα ΗΜΜΥ. Τομέας Ηλεκτρονικής} \Department{Τμήμα ΗΜΜΥ. Τομέας Ηλεκτρονικής}
\ClassName{Ασαφή Συστήματα (Υπολογιστική Νοημοσύνη)} \ClassName{Ασαφή Συστήματα (Υπολογιστική Νοημοσύνη)}
@ -87,7 +87,7 @@
\section{Εισαγωγή} \section{Εισαγωγή}
Στην εργασία αυτή εξετάζεται ο έλεγχος του συστήματος Στην εργασία αυτή (Σειρά 15), εξετάζεται ο έλεγχος του συστήματος
$G_p(s)=\frac{10}{(s+1)(s+9)}$ $G_p(s)=\frac{10}{(s+1)(s+9)}$
με δύο προσεγγίσεις: (i) κλασικός PI και (ii) ασαφής ελεγκτής τύπου FuzzyPI (Mamdani). με δύο προσεγγίσεις: (i) κλασικός PI και (ii) ασαφής ελεγκτής τύπου FuzzyPI (Mamdani).
Στόχος είναι η ικανοποίηση προδιαγραφών μεταβατικής απόκρισης (υπερύψωση, χρόνος ανόδου/αποκατάστασης) και η σύγκριση της ικανότητας παρακολούθησης αναφορών. Στόχος είναι η ικανοποίηση προδιαγραφών μεταβατικής απόκρισης (υπερύψωση, χρόνος ανόδου/αποκατάστασης) και η σύγκριση της ικανότητας παρακολούθησης αναφορών.

6
Work 2/report/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
# LaTeX auxiliary files
*.aux
*.log
*.out
*.synctex.gz

@ -0,0 +1 @@
Subproject commit 74ec4b5f6c66382e5f1b6d2e6930897e4ed53ea6

Binary file not shown.

View File

@ -0,0 +1,209 @@
%
% !TEX TS-program = xelatex
% !TEX encoding = UTF-8 Unicode
% !TEX spellcheck = el-GR
%
% Fuzzy Systems Assignment 2
%
% Requires compilation with pdfLaTeX or XeLaTeX
%
% authors:
% Χρήστος Χουτουρίδης ΑΕΜ 8997
% cchoutou@ece.auth.gr
% Options:
%
% 1) mainlang=<language>
% Default: english
% Set the default language of the document which affects hyphenations,
% localization (section, dates, etc...)
%
% example: \documentclass[mainlang=greek]{AUThReport}
%
% 2) <language>
% Add hyphenation and typesetting support for other languages
% Currently supports: english, greek, german, frenc
%
% example: \documentclass[english, greek]{AUThReport}
%
% 3) short: Requests a shorter title for the document
% Default: no short
%
% example: \documentclass[short]{AUThReport}
%
\documentclass[a4paper, 11pt, mainlang=greek, english]{AUThReport/AUThReport}
\CurrentDate{\today}
% Greek report document setup suggestions
%---------------------------------
% \WorkGroup{Ομάδα Χ}
\AuthorName{Χρήστος Χουτουρίδης}
\AuthorAEM{8997}
\AuthorMail{cchoutou@ece.auth.gr}
%\CoAuthorName{Όνομα Επίθετο}
%\CoAuthorAEM{1234}
%\CoAuthorMail{xxx@ece.auth.gr}
\DocTitle{Εργασία 2}
\DocSubTitle{Car Control - Σειρά 3}
\Department{Τμήμα ΗΜΜΥ. Τομέας Ηλεκτρονικής}
\ClassName{Ασαφή Συστήματα (Υπολογιστική Νοημοσύνη)}
\InstructorName{Θεοχάρης Ιωάννης}
\InstructorMail{theochar@ece.auth.gr}
\CoInstructorName{Χαδουλός Χρήστος}
\CoInstructorMail{christgc@auth.gr}
\usepackage{float}
\usepackage{minted}
\usepackage{xcolor} %
\usepackage{amsmath, amssymb, amsfonts}
\usepackage{diagbox}
%\usepackage{tabular}
\setminted[cpp]{
fontsize=\small,
breaklines,
autogobble,
baselinestretch=1.1,
tabsize=2,
numbersep=8pt,
gobble=0
}
\newcommand{\repo}{https://git.hoo2.net/hoo2/FuzzySystems/src/branch/master/Work\%202}
\begin{document}
% Request a title page or header
\InsertTitle
%\InsertTitle[img/background.png][0.8\textwidth][2cm]
\section{Εισαγωγή}
Στην παρούσα εργασία σχεδιάστηκε και αξιολογήθηκε ένας \textbf{ελεγκτής ασαφούς λογικής (FLC)} τύπου Mamdani για το πρόβλημα \textit{Car Control} (Σειρά~3). Το όχημα κινείται σε επίπεδο με \emph{σκαλοπάτια}/εμπόδια και στόχος είναι να ακολουθεί μια ασφαλή τροχιά, λαμβάνοντας ως πληροφορία μόνο τις \emph{αποστάσεις από τα εμπόδια} και τον \emph{προσανατολισμό} του.
Ο ελεγκτής υλοποιεί κανόνες της μορφής
\[
\text{IF } d_V \text{ is } \{S,M,L\} \text{ AND } d_H \text{ is } \{S,M,L\} \text{ AND } \theta \text{ is } \{N,ZE,P\} \text{ THEN } \Delta\theta \text{ is } \{N,ZE,P\},
\]
με τελεστές $ \mathrm{AND}:\min $, $ \mathrm{OR}:\max $, συνεπαγωγή $\min$, σύνθεση/συσσώρευση $\mathrm{sum}$ και αποασαφοποίηση $\mathrm{centroid}$ (COA), όπως ζητείται.
Η ανάπτυξη έγινε σε \textit{MATLAB}.
Το FIS δημιουργήθηκε μέσω του \textit{Fuzzy Logic Designer} (GUI) και αποθηκεύτηκε σε αρχείο \texttt{.fis}.
Η προσομοίωση της κίνησης και η παραγωγή των αποτελεσμάτων έγιναν προγραμματιστικά.
\subsection{Παραδοτέα}
Τα παραδοτέα της εργασίας αποτελούνται από:
\begin{itemize}
\item Την παρούσα αναφορά.
\item Τον κατάλογο \textbf{source}, με τον κώδικα της matlab.
\item Το \href{\repo}{σύνδεσμο με το αποθετήριο} που περιέχει τον κώδικα της matlab καθώς και αυτόν της αναφοράς.
\end{itemize}
\section{Υλοποίηση}
Πριν τη στοχοθετημένη αξιολόγηση, περιγράφεται συνοπτικά η αρχιτεκτονική της υλοποίησης.
Στόχος μας ήταν ένα \emph{αυτοτελές} σενάριο προσομοίωσης που να συνδυάζει:
\begin{itemize}
\item Ένα "νοητό" περιβάλλον με σκαλοπάτια/τοίχους
\item Την κινηματική του οχήματος
\item Τον ασαφή ελεγκτή.
\end{itemize}
Στο σχήμα \ref{fig:fcl_surface} φαίνεται το περιβάλλον της εργασίας.
\InsertFigure{!ht}{0.65}{fig:fcl_surface}{img/Terain.png}{Απεικόνιση του περιβάλλοντος με σκιασμένες περιοχές.}
Για να διατηρηθεί καθαρή διεπαφή, το περιβάλλον και η κινηματική ενσωματώθηκαν σε δύο βοηθητικές συναρτήσεις, ενώ ο ελεγκτής ορίστηκε σε ανεξάρτητη συνάρτηση/αντικείμενο FIS.
Η προσομοίωση εκτελείται από ένα κύριο script που διακρητοποιεί τον χρόνο, τροφοδοτεί τον ελεγκτή με μετρήσεις και ενημερώνει την κατάσταση.
\subsection{\texttt{wallDistance}}
Η \texttt{wallDistance($corners,x,y$)} υλοποιεί τον ``αισθητήρα'' του περιβάλλοντος.
Δεδομένων των \emph{γωνιών} που ορίζουν τα σκαλοπάτια (πίνακας \texttt{corners} με σημεία $(x_i, y_i)$), υπολογίζει:
\begin{itemize}
\item $d_h$: την \emph{οριζόντια} απόσταση μέχρι τον επόμενο τοίχο στα δεξιά του οχήματος ($x$-διεύθυνση),
\item $d_v$: την \emph{κάθετη} απόσταση μέχρι τον πλησιέστερο ``πάτο'' κάτω από το όχημα ($y$-διεύθυνση).
\end{itemize}
Ο αλγόριθμος ταξινομεί κατάλληλα τα \texttt{corners} (με \texttt{sortrows}) και επιλέγει τα \emph{ενεργά} τμήματα τοίχων ανάλογα με την τρέχουσα θέση $(x,y)$.
Τιμές $d_h,d_v \le 0$ αντιστοιχούν σε σύγκρουση, ενώ $\infty$ δηλώνει απουσία τοίχου προς την εξεταζόμενη κατεύθυνση.
Οι μετρήσεις κατόπιν \emph{κορεσμού} $[0,1]$ χρησιμοποιούνται αυτούσιες ως είσοδοι του FIS, όπως ορίζει η εκφώνηση.
\subsection{\texttt{moveCar}}
Η \texttt{moveCar($x,y,\theta,\Delta\theta$)} υλοποιεί τη στοιχειώδη κινηματική: πρώτα εφαρμόζεται η διόρθωση γωνίας $\theta \leftarrow \theta+\Delta\theta$, έπειτα ενημερώνεται η θέση
\[
x \leftarrow x + v\,T_s \cos(\theta), \quad
y \leftarrow y + v\,T_s \sin(\theta),
\]
με σταθερό μέτρο ταχύτητας $v$ και περίοδο δειγματοληψίας $T_s$.
Η γωνία χρησιμοποιείται σε \emph{μοίρες} ώστε να είναι συμβατή με τα διαστήματα της εκφώνησης.
\subsection{\texttt{carFLC}}
Ο ασαφής ελεγκτής είναι Mamdani με:
\begin{itemize}
\item \textbf{Εισόδους:} $d_h\in[0,1]$, $d_v\in[0,1]$, $\theta\in[-180,180]$ (μοίρες).
\item \textbf{Έξοδο:} $\Delta\theta\in[-130,130]$ (μοίρες).
\end{itemize}
Για $d_h,d_v$ χρησιμοποιούνται τριγωνικές MF $\{S,M,L\}$, ενώ για $\theta$ και $\Delta\theta$ οι MF $\{N,ZE,P\}$ όπως δίνονται στην εκφώνηση.
Οι τελεστές είναι:
\[
\mathrm{AND}=\min,\quad \mathrm{OR}=\max,\quad \mathrm{Implication}=\min,\quad
\mathrm{Aggregation}=\mathrm{sum},\quad \mathrm{Defuzzification}=\mathrm{centroid}.
\]
Το \texttt{.fis} δημιουργήθηκε με το \emph{Fuzzy Logic Designer} και αποθηκεύτηκε ως \texttt{CarFLC.fis}.
Στο σχήμα \ref{fig:fcl_rules} φαίνεται ένα στηγμιότηπο με τους κανόνες που χρησιμοποιήθηκαν για τον ελεγκτή.
Δυστυχώς, από την προηγούμενη εργασία μέχρι και αυτή, δεν προλάβαμε να γίνουμε ειδικοί, επομένως οι κανόνες βασίζονται και πάλι στη δική μας "φτωχή" προσέγγιση.
\InsertFigure{!ht}{0.95}{fig:fcl_rules}{img/FLC_Rules.png}{Ενδεικτικό στιγμιότυπο κανόνων.}
Στο σχήμα \ref{fig:fcl_surface} βλέπουμε και την επιφάνεια των κανόνων ως συνάρτηση των εισόδων των αποστάσεων.
\InsertFigure{!ht}{0.7}{fig:fcl_surface}{../source/FLC_surface_edit.png}{Ενδεικτική επιφάνεια βάσης κανόνων ($\Delta\theta$ ως συνάρτηση δύο εισόδων).}
\subsection{\texttt{runSimulation}}
Το κύριο script εκτελεί την προσομοίωση: για κάθε χρονικό βήμα καλεί διαδοχικά \texttt{wallDistance} $\rightarrow$ \texttt{evalfis} $\rightarrow$ \texttt{moveCar}, αποθηκεύοντας την τροχιά.
Η διαδικασία επαναλαμβάνεται για τις τρεις αρχικές γωνίες $\theta_0\in\{-45^\circ,0^\circ,45^\circ\}$.
Στην δική μας έκδοση το όχημα εκκινεί από τη θέση $(x_{init},y_{init}) = (3.8, 0.5)$.
Η εκτέλεση τερματίζει είτε σε σύγκρουση (οριακή τιμή $d_H$ ή $d_V\le0$) είτε όταν το όχημα φτάσει στο $(x_d,y_d) = (10, 3.2)$.
\section{Ζητούμενα}
Τα ζητούμενα (τροχιές για διαφορετικές αρχικές γωνίες) παράγονται αυτόματα από το \texttt{runSimulation} και αποθηκεύονται ως εικόνες.
Παρακάτω παρατίθενται οι τροχιές από την εκτέλεση του script.
\InsertFigure{!ht}{0.85}{fig:car_track_min45}{../source/CarMovement_theta-45.png}{Πορεία οχήματος για αρχική γωνία $\theta_0=-45^\circ$.}
\InsertFigure{!ht}{0.85}{fig:car_track_0}{../source/CarMovement_theta0.png}{Πορεία οχήματος για αρχική γωνία $\theta_0=0^\circ$.}
\InsertFigure{!ht}{0.85}{fig:car_track_45}{../source/CarMovement_theta45.png}{Πορεία οχήματος για αρχική γωνία $\theta_0=45^\circ$.}
\subsection{Σχολιασμός}
Η λειτουργία του ελεγκτή είναι \emph{σταθερή} και \emph{ομαλή}: παρατηρούνται ομαλές καμπύλες χωρίς απότομες γωνίες, καθώς οι MF επικάλυψης εξομαλύνουν τις μεταβάσεις κανόνων.
Η σύγκλιση προς το επιθυμητό $x_d$ επιτυγχάνεται και στις τρεις περιπτώσεις, με την τροχιά να ακολουθεί πρακτικά τα εμπόδια.
Ωστόσο, η συμπεριφορά δεν είναι ιδανική για δύο λόγους:
\begin{enumerate}
\item Ο ελεγκτής \textbf{δεν} λαμβάνει άμεση πληροφορία για το \emph{στόχο} ($x_d,y_d$).
Bασίζεται μόνο στις αποστάσεις από εμπόδια και στη γωνία, άρα η κάθετη διόρθωση ($y$) δεν ``οδηγείται'' ρητά από το σφάλμα έως τον στόχο.
\item Οι αποστάσεις $d_h,d_v$ \textbf{ψαλιδισμένες} στο $[0,1]$ περιορίζουν τη δυναμική περιοχή (lossy αισθητηριακή πληροφορία σε μεγάλες αποστάσεις), κάτι που επιβαρύνει την προσέγγιση ειδικά σε ύψος.
\end{enumerate}
Παρά τους περιορισμούς, ο FLC επιτυγχάνει αποφυγή εμποδίων και καλή ευθυγράμμιση με χαμηλό υπολογιστικό κόστος και υψηλή ερμηνευσιμότητα κανόνων.
\section {Συμπεράσματα}
Αναπτύξαμε έναν Mamdani FLC για το πρόβλημα \textit{Car Control} (Σειρά~3) με εισόδους $(d_h,d_v,\theta)$ και έξοδο $\Delta\theta$. Ο ελεγκτής, με κανόνες τύπου IF--THEN και COA αποασαφοποίηση, κατεύθυνε το όχημα με ομαλές τροχιές, αποφεύγοντας τα εμπόδια και επιτυγχάνοντας τη μετάβαση στο επιθυμητό επίπεδο.
\textbf{Στα θετικά}, είχαμε την ομαλότητα ελέγχου, ερμηνευσιμότητα κανόνων, επαναληψιμότητα σε διαφορετικές αρχικές γωνίες, απλή παραμετροποίηση.
\textbf{Στα αρνητικά}, είχαμε την έλλειψη ρητής πληροφορίας στόχου $(x_d,y_d)$, περιορισμένη δυναμική πληροφορία αποστάσεων λόγω κορεσμού $[0,1]$.
Θεωρούμε πως το σύστημα θα βελτιωνόταν αρκετά με:
\begin{itemize}
\item Προσθήκη επιπλέον εισόδου με σφάλμα προς τον στόχο (πχ.\ $e_x=x_d-x,\ e_y=y_d-y$),
\item Ανακλιμάκωση ή προσαρμοστικό κορεσμό των αποστάσεων,
\item Χρήση υβριδικού ελεγκτής (FLC για αποφυγή εμποδίων + PD/TSK για καθοδήγηση στον στόχο).
\end{itemize}
\end{document}

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

3
Work 2/source/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Matlab auxiliary files
*.asv

73
Work 2/source/CarFLC.fis Normal file
View File

@ -0,0 +1,73 @@
[System]
Name='CarFLC'
Type='mamdani'
Version=2.0
NumInputs=3
NumOutputs=1
NumRules=27
AndMethod='min'
OrMethod='max'
ImpMethod='min'
AggMethod='sum'
DefuzzMethod='centroid'
[Input1]
Name='dh'
Range=[0 1]
NumMFs=3
MF1='S':'trimf',[0 0 0.5]
MF2='M':'trimf',[0 0.5 1]
MF3='L':'trimf',[0.5 1 1]
[Input2]
Name='dv'
Range=[0 1]
NumMFs=3
MF1='S':'trimf',[0 0 0.5]
MF2='M':'trimf',[0 0.5 1]
MF3='L':'trimf',[0.5 1 1]
[Input3]
Name='theta'
Range=[-180 180]
NumMFs=3
MF1='N':'trimf',[-180 -180 0]
MF2='ZE':'trimf',[-180 0 180]
MF3='P':'trimf',[0 180 180]
[Output1]
Name='dtheta'
Range=[-130 130]
NumMFs=3
MF1='N':'trimf',[-130 -130 0]
MF2='ZE':'trimf',[-130 0 130]
MF3='P':'trimf',[0 130 130]
[Rules]
1 1 1, 3 (1) : 1
1 2 1, 3 (1) : 1
1 3 1, 3 (1) : 1
2 1 1, 3 (1) : 1
2 2 1, 2 (1) : 1
2 3 1, 2 (1) : 1
3 1 1, 3 (1) : 1
3 2 1, 3 (1) : 1
3 3 1, 3 (1) : 1
1 1 2, 3 (1) : 1
1 2 2, 3 (1) : 1
1 3 2, 3 (1) : 1
2 1 2, 2 (1) : 1
2 2 2, 2 (1) : 1
2 3 2, 2 (1) : 1
3 1 2, 2 (1) : 1
3 2 2, 2 (1) : 1
3 3 2, 2 (1) : 1
1 1 3, 2 (1) : 1
1 2 3, 2 (1) : 1
1 3 3, 2 (1) : 1
2 1 3, 2 (1) : 1
2 2 3, 2 (1) : 1
2 3 3, 1 (1) : 1
3 1 3, 2 (1) : 1
3 2 3, 2 (1) : 1
3 3 3, 1 (1) : 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

77
Work 2/source/mkFIS.m Normal file
View File

@ -0,0 +1,77 @@
%
% Local script to create FIS (w/o the GUI crap)
%
% FIS control
% R2025 compatibility:
% - newfis->mamfis
% - defuzzMethod='cos' -> AggregationMethod="sum", DefuzzificationMethod="centroid"
fis = mamfis( ...
AndMethod="min", ...
OrMethod="max", ...
ImplicationMethod="min", ...
AggregationMethod="sum", ...
DefuzzificationMethod="centroid" );
% Inputs
fis = addInput(fis,[0 1],'Name','dh');
fis = addMF(fis,'dh','trimf',[0 0 0.5],'Name','S');
fis = addMF(fis,'dh','trimf',[0 0.5 1],'Name','M');
fis = addMF(fis,'dh','trimf',[0.5 1 1],'Name','L');
fis = addInput(fis,[0 1],'Name','dv');
fis = addMF(fis,'dv','trimf',[0 0 0.5],'Name','S');
fis = addMF(fis,'dv','trimf',[0 0.5 1],'Name','M');
fis = addMF(fis,'dv','trimf',[0.5 1 1],'Name','L');
fis = addInput(fis,[-180 180],'Name','theta');
fis = addMF(fis,'theta','trimf',[-180 -180 0],'Name','N');
fis = addMF(fis,'theta','trimf',[-180 0 180],'Name','ZE');
fis = addMF(fis,'theta','trimf',[ 0 180 180],'Name','P');
% Output
fis = addOutput(fis,[-130 130],'Name','dtheta');
fis = addMF(fis,'dtheta','trimf',[-130 -130 0],'Name','N');
fis = addMF(fis,'dtheta','trimf',[-130 0 130],'Name','ZE');
fis = addMF(fis,'dtheta','trimf',[ 0 130 130],'Name','P');
% Rules
fis = addRule(fis, "IF theta IS N dh IS S AND dv IS S AND THEN dtheta IS P");
fis = addRule(fis, "IF theta IS N dh IS S AND dv IS M AND THEN dtheta IS P");
fis = addRule(fis, "IF theta IS N dh IS S AND dv IS L AND THEN dtheta IS P");
fis = addRule(fis, "IF theta IS N dh IS M AND dv IS S AND THEN dtheta IS P");
fis = addRule(fis, "IF theta IS N dh IS M AND dv IS M AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS N dh IS M AND dv IS L AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS N dh IS L AND dv IS S AND THEN dtheta IS P");
fis = addRule(fis, "IF theta IS N dh IS L AND dv IS M AND THEN dtheta IS P");
fis = addRule(fis, "IF theta IS N dh IS L AND dv IS L AND THEN dtheta IS P");
fis = addRule(fis, "IF theta IS ZE dh IS S AND dv IS S AND THEN dtheta IS P");
fis = addRule(fis, "IF theta IS ZE dh IS S AND dv IS M AND THEN dtheta IS P");
fis = addRule(fis, "IF theta IS ZE dh IS S AND dv IS L AND THEN dtheta IS P");
fis = addRule(fis, "IF theta IS ZE dh IS M AND dv IS S AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS ZE dh IS M AND dv IS M AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS ZE dh IS M AND dv IS L AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS ZE dh IS L AND dv IS S AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS ZE dh IS L AND dv IS M AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS ZE dh IS L AND dv IS L AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS P dh IS S AND dv IS S AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS P dh IS S AND dv IS M AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS P dh IS S AND dv IS L AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS P dh IS M AND dv IS S AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS P dh IS M AND dv IS M AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS P dh IS M AND dv IS L AND THEN dtheta IS N");
fis = addRule(fis, "IF theta IS P dh IS L AND dv IS S AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS P dh IS L AND dv IS M AND THEN dtheta IS ZE");
fis = addRule(fis, "IF theta IS P dh IS L AND dv IS L AND THEN dtheta IS N");
writeFIS(fis,'CarFLC');
f1 = figure('Name','FLC surface'); gensurf(fis); grid on;
exportgraphics(f1, sprintf('FLC_surface.png'), 'Resolution', 300);

15
Work 2/source/moveCar.m Normal file
View File

@ -0,0 +1,15 @@
function [x_new, y_new, theta_new] = moveCar(x, y, theta, dtheta)
%MOVECAR updates car's position based on previous state
% Detailed explanation goes here
global Speed_mag;
global Ts;
% Stear and then calculate the new position
theta_new = theta + dtheta;
x_new = x + Speed_mag * Ts * cos(toRadians("degrees", theta_new));
y_new = y + Speed_mag * Ts * sin(toRadians("degrees", theta_new));
end

View File

@ -0,0 +1,88 @@
%% Car - Simulation
%
% Assignment 2 in Fuzzy systems
%
% author:
% Christos Choutouridis ΑΕΜ 8997
% cchoutou@ece.auth.gr
%
clear; clc; close all;
global Speed_mag;
global Ts;
% Configuration
% ----------------------
Speed_mag = 0.05;
Ts = 1;
% Givents
% ----------------------
corners = [5 1 ; 6 2 ; 7 3];
x_init = 3.8;
y_init = 0.5;
x_final = 10;
y_final = 3.2;
theta_init = [-45 0 45];
% Saturation between min: m and max: M
sat = @(x, m, M) max(m, min(M, x));
% Load control
flc = readfis('CarFLC');
t = 0:Ts:250;
for i = 1:length(theta_init)
x = x_init;
y = y_init;
theta = theta_init(i);
X = zeros(size(t));
Y = zeros(size(t));
End=length(t);
for k=1:End
[dh, dv] = wallDistance(corners, x, y);
if isfinite(dh) && ~isfinite(dv) && (dh <=0 || dv <= 0)
End = k-1;
fprintf('Car crashed!! - Stop simulation');
break;
end
dtheta = evalfis(flc, [sat(dh, 0, 1) sat(dv, 0, 1) theta]);
[x, y, theta] = moveCar(x, y, theta, dtheta);
X(k) = x; Y(k) = y;
if x >= x_final
End = k-1;
break;
end
end
figure(i); clf; hold on; grid on; axis equal;
xlim([2 11]); ylim([-1 4]);
xlabel('x [m]'); ylabel('y [m]');
title( ...
"Car movement $(\theta_0 =" + theta_init(i)+ "^{\circ})$", ...
'Interpreter','latex', ...
'FontSize', 16);
% Walls
fill([5 6 6 5],[0 0 1 1],[0.5 0.5 0.5],'FaceAlpha',0.4,'EdgeColor','none');
fill([6 7 7 6],[0 0 2 2],[0.5 0.5 0.5],'FaceAlpha',0.4,'EdgeColor','none');
fill([7 10 10 7],[0 0 3 3],[0.5 0.5 0.5],'FaceAlpha',0.4,'EdgeColor','none');
plot(X(1:End), Y(1:End), '-', 'LineWidth', 1.5);
hold on;
plot(X(1), Y(1), 'go', 'MarkerFaceColor', 'g'); % begin
plot(X(End), Y(End), 'ro', 'MarkerFaceColor', 'r'); % end
hold off;
filename = sprintf('CarMovement_theta%d.png', theta_init(i));
saveas(gcf, filename);
end

View File

@ -0,0 +1,45 @@
function [dh, dv] = wallDistance(corners, x, y)
% Calculates the distances from the walls.
% - Negative value means colision
% - Inf value means no wall in this direction
%
% Inputs:
% corners[] : corner matrix (each line is a corner point)
% x: Car's x position
% y: Car's y position
% Outputs:
% dh: Horizontal distance from wall
% dv: Vertical distance from wall
% Calculate the distances in the x direction
srt_corners = sortrows(corners, 2);
active_corners = -Inf(size(corners));
for i=1:length(srt_corners)
if srt_corners(i, 2) >= y
active_corners = srt_corners(i:end, :);
break;
end
end
dx = active_corners(:, 1) - x; % Walls are on the right
dh = min(dx); % Minimum distance in x direction
% Calculate the distances in the y direction
srt_corners = sortrows(corners, 1, 'descend');
active_corners = -Inf(size(corners));
for i=1:length(srt_corners)
if srt_corners(i, 1) <= x
active_corners = srt_corners(i:end, :);
break;
end
end
dy = y - active_corners(:, 2); % Walls are on the bottom
dv = min(dy); % Minimum distance in y direction
if ~isfinite(dh) dh = Inf; end
if ~isfinite(dv) dv = Inf; end
end