Compare commits

..

48 Commits

Author SHA1 Message Date
db402d3d71 fix paths in raports 2021-04-02 22:47:20 +02:00
84e47b1c96 refactor 2021-04-02 22:39:43 +02:00
Adam Osiowy
10d90b5f65 poprawka w raporcie 2020-06-09 22:57:06 +02:00
Adam Osiowy
b423a21a44 poprawka w raporcie 2020-06-09 22:54:14 +02:00
643e343f1e raport koncowy 2020-06-09 22:48:58 +02:00
Adam Osiowy
a5259eacae final 2020-06-09 22:16:34 +02:00
ecf83b179c Update 'raport_adamB.md' 2020-05-20 08:27:46 +00:00
6317db6ad2 Update 'raport_adamB.md' 2020-05-20 07:35:29 +00:00
be07f997f7 Update 'raport_adamB.md' 2020-05-20 06:09:07 +00:00
d613f40a7a Update 'raport_adamB.md' 2020-05-20 06:02:19 +00:00
7853c2addd pip freeze reqs update 2020-05-19 21:20:04 +02:00
c44c16e836 final 2020-05-19 21:14:55 +02:00
cedb309f02 raport 2020-05-18 21:34:26 +02:00
c0b52698a7 kod dziala - nie wiem tylko czy na pewno z dobrymi procentami 2020-05-17 18:51:04 +02:00
e3787aaa6e chwilowo wyswietlanie datasetu z opisem 2020-05-16 18:09:18 +02:00
e3d2127c2b Zaktualizuj 'adamORaport.md' 2020-05-13 07:31:29 +00:00
947427a886 Zaktualizuj 'adamORaport.md' 2020-05-13 07:14:14 +00:00
Adam Osiowy
19cd5c4652 Merge branch 'master' of https://git.wmi.amu.edu.pl/s444350/SZI-Smieciarka into adamO 2020-05-13 01:19:51 +02:00
Adam Osiowy
07d8eb5268 poprawki estetyczne 2020-05-13 01:14:28 +02:00
Adam Osiowy
00d0db8dcb stworzony raport 2020-05-13 01:06:23 +02:00
ade150528e oczyszczenie 2020-05-12 22:14:41 +02:00
Adam Osiowy
015b60a006 podprojekt indywidualny 2020-05-12 19:26:08 +02:00
Adam Osiowy
fa6c551783 aktualizacja tworzenia pliku z danymi h5 2020-05-12 12:21:31 +02:00
Adam Osiowy
57381d630a utworzone pliki projektu indywidualnego 2020-05-12 00:58:26 +02:00
Adam Osiowy
e06cbf4acd dodany wybór osoby 2020-05-12 00:02:05 +02:00
Adam Osiowy
bb100e9f8d przywrocone zdj smieci 2020-05-11 23:06:22 +02:00
56645627c8 Zaktualizuj 'uczenie_kacper.py' 2020-05-11 16:49:50 +00:00
15b1a0bd3c Merge branch 'master' of https://git.wmi.amu.edu.pl/s444350/SZI-Smieciarka into kacperB 2020-05-11 18:47:17 +02:00
6a5e25e048 screeny do raportu 2020-05-11 18:46:33 +02:00
a0c5a433fd Dodaj 'kacperRaport.md'
raport indywidualny kacper
2020-05-11 16:45:44 +00:00
a4aabbc772 podprojekt kacper update 2020-05-07 17:21:04 +02:00
b12fa77b91 podprojekt kacper update 2020-05-07 17:07:57 +02:00
b9fda1e459 podprojekt kacper update 2020-05-07 17:05:22 +02:00
a0e4350f61 podprojekt kacper 2020-05-07 16:57:37 +02:00
669c22dc1c podprojekt kacper 2020-05-07 16:55:31 +02:00
Adam Osiowy
ec572b93cb raport 2020-04-28 18:18:13 +02:00
Adam Osiowy
282e0d39f7 merge 2020-04-28 17:34:47 +02:00
Adam Osiowy
fc0f59ba53 stworzone screeny 2020-04-28 17:33:36 +02:00
991b816ba2 Merge branch 'master' of https://git.wmi.amu.edu.pl/s444350/SZI-Smieciarka into kacperB 2020-04-28 17:32:38 +02:00
9eca938713 stepcost dodany 2020-04-28 17:31:16 +02:00
Adam Osiowy
8d7d85fc35 utworzona struktura pliku 2020-04-28 16:17:42 +02:00
Adam Osiowy
ea2bda2b13 utworzony plik route-planning.md 2020-04-28 15:44:05 +02:00
69d8d74d26 lekkie oczyszczenie 2020-04-26 16:23:32 +02:00
090eb268e6 pelny ruch smieciarki astarem 2020-04-26 16:13:54 +02:00
d758feeda2 Merge branch 'master' of https://git.wmi.amu.edu.pl/s444350/SZI-Smieciarka into kacperB 2020-04-26 14:20:01 +02:00
c21bc78136 Merge branch 'master' of https://git.wmi.amu.edu.pl/s444350/SZI-Smieciarka into kacperB 2020-04-26 14:10:19 +02:00
a373633571 kolejna poprawa astara 2020-04-26 13:59:43 +02:00
c96e45bd08 poprawa astara 2020-04-26 13:56:26 +02:00
4163 changed files with 1651 additions and 697 deletions

3
.gitignore vendored
View File

@ -2,4 +2,5 @@ venv/
.vscode/
.ideagit
.idea
__pycache__/
__pycache__/
/resources/smieci w kontenerach

View File

@ -1,56 +0,0 @@
import heapq
def heurystyka(obiekty, a, b):
heur = abs((b[0] - a[0])) + abs((b[1] - a[1]))
if obiekty["plansza"][b[0], b[1]].jestDomem is True:
heur += 2
return heur
def astar(obiekty, start, cel):
sasiedzi = [(0, 1), (0, -1), (1, 0), (-1, 0)]
close_set = set()
came_from = {}
hscore = {start: heurystyka(obiekty, start, cel)}
gscore = {start: 0}
fscore = {start: heurystyka(obiekty, start, cel)}
oheap = []
dodatkowy_koszt = 0
heapq.heappush(oheap, (fscore[start], start))
while oheap:
current = heapq.heappop(oheap)[1]
if current == cel:
obiekty["plansza"][current[0], current[1]].setKolor((255, 0, 0))
data = []
while current in came_from:
data.append(current)
current = came_from[current]
return data[::-1]
close_set.add(current)
obiekty["plansza"][current[0], current[1]].setKolor((255, 0, 0))
for i, j in sasiedzi:
sasiad = current[0] + i, current[1] + j
if 14 < sasiad[0] or sasiad[0] < 0:
continue
elif 14 < sasiad[1] or sasiad[1] < 0:
continue
elif 6 <= sasiad[0] <= 7 and 10 <= sasiad[1] <= 11:
continue
tentative_h_score = heurystyka(
obiekty, sasiad, cel) + heurystyka(obiekty, current, sasiad)
if sasiad in [i[1] for i in oheap] and tentative_h_score < hscore.get(current, 0):
continue
elif sasiad not in close_set and sasiad not in [i[1] for i in oheap]:
came_from[sasiad] = current
hscore[sasiad] = tentative_h_score
fscore[sasiad] = tentative_h_score + gscore[current]
gscore[sasiad] = gscore[current] + \
heurystyka(obiekty, current, sasiad)
heapq.heappush(oheap, (fscore[sasiad], sasiad))
obiekty["plansza"][sasiad[0], sasiad[1]].setKolor((0, 255, 0))
return False

View File

@ -1,68 +0,0 @@
# Sztuczna Inteligencja
**Temat projektu:** Inteligenta Śmieciarka
**Zespół:** Kacper Borkowski, Adam Borowski, Adam Osiowy
---
## 1. Ogólne działanie:
![gif](resources/screenShots/gifProjektu.gif)
---
## 2. Struktura katalogów:
![katalogi](resources/screenShots/strukturaKatalogu.png)
**Resources**:
- _plansza_ - folder zawierający zdjęcia niezbędne do generowania planszy - domy, jezioro, pojemniki, wysypisko,
- _śmieci_ - zawiera podfoldery z klaysifkacją zdjęć śmieci,
- _śmieci w kontenerach_ - folder, który będzie zawierał posegregowane już smieci
**Pliki**:
**[game.py](game.py)** - plik zawierający całą funkcjonalność projektu:
- główna pętla programu,
- tworzenie planszy,
- tworzenie i usytuowanie obiektów z katalogu [modeli](modele.py),
- generowanie tekstowej interpretacji zebranej wiedzy
**[main.py](main.py)** - klasa odpowiedzialna za uruchomienie programu
**[modele.py](modele.py)** - zawiera klasy aplikacji
**[requirements.txt](requirements.txt)** - posiada biblioteki niezbędne do uruchomienia programu, które instalujemy za pomocą poniższego polecenia:
```
pip install -r requirements.txt
```
---
## 3. Opis funkcjonalności programu:
* śmieciarka porusza się w losowy sposób po planszy 15 x 15 (koloruje na niebiesko przebytą trasę)
![ruch śmieciarki](resources/screenShots/randMove.png)
* domy generowane są losowo na mapie z pominięciem kolizji z innymi obiektami
![generowanie_domów](resources/screenShots/wspolrzedneDomow.png)
* pozycja wysypiska, przeszkody (jeziorko) i kontenerów jest statyczna
![statyczna_pozycja](resources/screenShots/statycznaPozycja.png)
* w kontenerach przechowywane będą posegregowane, odpowiednio według kategorii, zdjęcia śmieci
* zdjęcia śmieci będą przydzielane w sposób losowy do każdego z domów na planszy
![losowanie_śmieci](resources/screenShots/wyborSmieci.png)
* śmieciarka zbiera śmieci po najechaniu na pozycję danego domu
* po każdym uruchomieniu programu tworzona jest struktura katalogów dla posegregowanych śmieci
![tworzenie_struktury](resources/screenShots/tworzenieStrukturyKatalogow.png)
* śmieciarka sprawdza w każdym ruchu czy nie dojdzie do kolizji z innym obiektem lub nie wyjedzie poza planszę
![sprawdzanie_kolizcji](resources/screenShots/sprawdzanieKolizji.png)
* po prawej stronie wypisywane są aktualne, najważniejsze informacje
![wiedza](resources/screenShots/wiedzaPoPrawejStronie.png)
* każdy obiekt na planszy posiada atrybuty odpowiedzalne za
przechowywanie wiedzy o danym obiekcie np.: obiekt śmieciarka przechowuje informacje o odwiedzonych domach
![atrybuty](resources/screenShots/atrybutySmieciarki.png)

266
game.py
View File

@ -1,266 +0,0 @@
import pygame
import modele
import numpy as np
import random
import os
import shutil
import astar
pygame.init()
# kolory
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (40, 50, 200)
GREY = (128, 128, 128)
# wysokosc i szerokosc kazdej kratki
WIDTH = 60
HEIGHT = 60
# margines pomiedzy kratkami
MARGIN = 5
# rozmiar kratki
ILOSC_WIERSZY = 15
ILOSC_KOLUMN = 15
# rozmiar okna
WINDOW_SIZE = [1300, 980]
# TEST DODAWANIA SMIECI Z POJEDYNCZEGO DOMU DO FOLDERU KONTENERA ZE SZKLEM
# for d in lista_domow:
# for s in d.smieci:
# kontener_szklo.dodajSmiec(s)
def game():
obiekty = utworzObiekty()
# Petla az uzytkownik zamknie program
done = False
clock = pygame.time.Clock()
temp = True
# -------- Glowna petla programu -----------
while not done:
# obsluga zdarzen typu nacisniecie klawisza lub przycisku myszy
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
elif event.type == pygame.MOUSEBUTTONDOWN:
# Zapisywanie pozycji myszki po kliknieciu
pozycja_myszki = pygame.mouse.get_pos()
# Zamiana pozycji na konkretne koordy
kolumna = pozycja_myszki[0] // (WIDTH + MARGIN)
wiersz = pozycja_myszki[1] // (HEIGHT + MARGIN)
print("Click ", pozycja_myszki,
"Grid coordinates: ", wiersz, kolumna)
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
obiekty["smieciarka"].w_lewo()
if event.key == pygame.K_RIGHT:
obiekty["smieciarka"].w_prawo()
if event.key == pygame.K_UP:
obiekty["smieciarka"].w_gore()
if event.key == pygame.K_DOWN:
obiekty["smieciarka"].w_dol()
rysowaniePlanszy(obiekty)
while(temp):
obiekty["smieciarka"].astar_move(obiekty)
temp = False
clock.tick(7)
#start = obiekty["plansza"][0, 14]
#koniec = obiekty["plansza"][14, 0]
#print(astar.astar(obiekty, (0, 14), (14, 0)))
#print(len(astar.astar(start, koniec)))
pygame.quit()
def rysowaniePlanszy(obiekty):
obiekty["obraz"].fill(BLACK)
# rysowanie planszy
for i in range(ILOSC_WIERSZY):
for j in range(ILOSC_KOLUMN):
pygame.draw.rect(obiekty["obraz"],
obiekty["plansza"][i, j].kolor,
[(MARGIN + WIDTH) * obiekty["plansza"][i, j].pozY + MARGIN,
(MARGIN + HEIGHT) *
obiekty["plansza"][i, j].pozX + MARGIN,
WIDTH,
HEIGHT])
obiekty["obraz"].blit(pygame.image.load(
"resources/plansza/wysypisko.jpg"), (5, 5))
obiekty["obraz"].blit(pygame.image.load(
"resources/plansza/jezioro.png"), (395, 655))
obiekty["plansza"][6, 10].setJestPrzeszkoda(True)
obiekty["plansza"][6, 11].setJestPrzeszkoda(True)
obiekty["plansza"][7, 10].setJestPrzeszkoda(True)
obiekty["plansza"][7, 11].setJestPrzeszkoda(True)
obiekty["sprajty"].draw(obiekty["obraz"])
text_metal, text_papier, text_plastik, text_szklo, text_pozostale, text_odwiedzone_domy = liczSmieci(
obiekty["domy"], obiekty)
obiekty["obraz"].blit(obiekty["text_pozostalo"],
(1020, 240))
obiekty["obraz"].blit(text_metal, (1020, 280))
obiekty["obraz"].blit(text_plastik, (1020, 320))
obiekty["obraz"].blit(text_szklo, (1020, 360))
obiekty["obraz"].blit(text_papier, (1020, 400))
obiekty["obraz"].blit(text_pozostale, (1020, 440))
obiekty["obraz"].blit(text_odwiedzone_domy, (1020, 480))
pygame.display.update()
def utworzObiekty():
# Tworzenie planszy i kratek
plansza = np.array([[modele.Kratka(i, j) for i in range(ILOSC_KOLUMN)]
for j in range(ILOSC_WIERSZY)])
all_sprites_list = pygame.sprite.Group()
# smieciarka
smieciarka = modele.Smieciarka(10, 10)
plansza[10, 10].setKolor(BLUE)
plansza[10, 10].setObiekt(smieciarka)
# tworzenie wyswietlanego okna
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (0, 30)
obraz = pygame.display.set_mode(WINDOW_SIZE)
smieciarka.setObraz(obraz)
pygame.display.set_caption("Inteligentna śmieciarka")
# kontenery
if os.path.exists('resources/smieci w kontenerach'):
shutil.rmtree("resources/smieci w kontenerach")
os.makedirs('resources/smieci w kontenerach')
kontener_plastik = modele.Kontener(0, 0, "plastik")
kontener_plastik.setImage(pygame.image.load(
"resources/plansza/pojemnik_plastik.png"))
plansza[0, 0].setJestKontenerem(True)
plansza[0, 0].setObiekt(kontener_plastik)
kontener_metal = modele.Kontener(0, 4, "metal")
kontener_metal.setImage(pygame.image.load(
"resources/plansza/pojemnik_metal.png"))
plansza[0, 4].setJestKontenerem(True)
plansza[0, 4].setObiekt(kontener_metal)
kontener_organiczne = modele.Kontener(2, 2, "pozostale")
kontener_organiczne.setImage(pygame.image.load(
"resources/plansza/pojemnik_organiczne.png"))
plansza[2, 2].setJestKontenerem(True)
plansza[2, 2].setObiekt(kontener_organiczne)
kontener_papier = modele.Kontener(4, 0, "papier")
kontener_papier.setImage(pygame.image.load(
"resources/plansza/pojemnik_papier.png"))
plansza[4, 0].setJestKontenerem(True)
plansza[4, 0].setObiekt(kontener_papier)
kontener_szklo = modele.Kontener(4, 4, "szklo")
kontener_szklo.setImage(pygame.image.load(
"resources/plansza/pojemnik_szklo.png"))
plansza[4, 4].setJestKontenerem(True)
plansza[4, 4].setObiekt(kontener_szklo)
# domy
doms_array = ['resources/plansza/domy/dom1.png', 'resources/plansza/domy/dom2.png',
'resources/plansza/domy/dom3.png', 'resources/plansza/domy/dom4.png',
'resources/plansza/domy/dom5.png']
domy_lista = pygame.sprite.Group()
smieci_lista = [os.path.join(path, filename)
for path, dirs, files in os.walk("resources/smieci")
for filename in files]
# informacje o ilosci smieci w domach
font = pygame.font.SysFont("arial", 20, bold=True)
text_pozostalo = font.render("Pozostało śmieci w domach:", True, WHITE)
wspolrzedne_domow = modele.generujWspolrzedneDomow(10)
for i in range(len(wspolrzedne_domow)):
dom = modele.Dom(wspolrzedne_domow[i][0], wspolrzedne_domow[i][1])
dom.setImage(pygame.image.load(random.choice(doms_array)))
plansza[wspolrzedne_domow[i][0],
wspolrzedne_domow[i][1]].setJestDomem(True)
plansza[wspolrzedne_domow[i][0],
wspolrzedne_domow[i][1]].setObiekt(dom)
domy_lista.add(dom)
all_sprites_list.add(dom)
lista_domow = domy_lista.sprites()
for d in lista_domow:
for j in range(5):
smiec = random.choice(smieci_lista)
d.dodajSmiec(smiec)
smieci_lista.remove(smiec)
# ustawienie wysypiska, rozmiar wysypiska 5x5
for i in range(5):
for j in range(5):
plansza[i, j].setJestWysypiskiem(True)
all_sprites_list.add(kontener_plastik, kontener_metal, kontener_organiczne, kontener_papier, kontener_szklo,
smieciarka)
obiekty = {
"plansza": plansza,
"smieciarka": smieciarka,
"obraz": obraz,
"kontener_plastik": kontener_plastik,
"kontener_szklo": kontener_szklo,
"kontener_metal": kontener_metal,
"kontener_organiczne": kontener_organiczne,
"kontener_papier": kontener_papier,
"sprajty": all_sprites_list,
"domy": lista_domow,
"smieci": smieci_lista,
"font": font,
"text_pozostalo": text_pozostalo,
"wspolrzedne_domow": wspolrzedne_domow
}
smieciarka.setObiekty(obiekty)
smieciarka.setPlansza(plansza)
return obiekty
def liczSmieci(domy, obiekty):
ile_metalu = 0
ile_szkla = 0
ile_papieru = 0
ile_plastiku = 0
ile_pozostalych = 0
for d in domy:
for s in d.smieci:
if "metal" in s:
ile_metalu += 1
elif "paper" in s:
ile_papieru += 1
elif "plastic" in s:
ile_plastiku += 1
elif "glass" in s:
ile_szkla += 1
elif "trash" in s:
ile_pozostalych += 1
text_metal = obiekty["font"].render(
"Metal: " + str(ile_metalu), True, WHITE)
text_papier = obiekty["font"].render(
"Papier: " + str(ile_papieru), True, WHITE)
text_plastik = obiekty["font"].render(
"Plastik: " + str(ile_plastiku), True, WHITE)
text_szklo = obiekty["font"].render(
"Szkło: " + str(ile_szkla), True, WHITE)
text_pozostale = obiekty["font"].render(
"Pozostałe: " + str(ile_pozostalych), True, WHITE)
text_odwiedzone_domy = obiekty["font"].render(
"Odwiedzone domy: " + str(obiekty["smieciarka"].getOdwiedzoneDomy()), True, WHITE)
return text_metal, text_papier, text_plastik, text_szklo, text_pozostale, text_odwiedzone_domy

11
main.py
View File

@ -1,11 +0,0 @@
import pygame
import game
def main():
print("poczatek programu")
game.game()
if __name__ == '__main__':
main()

294
modele.py
View File

@ -1,294 +0,0 @@
import pygame
import game
import random
import os
import shutil
import astar
# wysokosc i szerokosc kazdej kratki
WIDTH = 60
HEIGHT = 60
# margines pomiedzy kratkami
MARGIN = 5
# kolory
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (40, 50, 200)
GREY = (128, 128, 128)
class Smieciarka(pygame.sprite.Sprite):
def __init__(self, x, y):
self.x = x
self.y = y
self.pozycja = (self.x, self.y)
self.image = pygame.image.load('resources/plansza/smieciarka.png')
self.obraz = None
self.ruch = 1
self.plastik = []
self.szklo = []
self.papier = []
self.metal = []
self.pozostale = []
self.odwiedzone_domy = 0
self.wspolrzedne_odwiedzonych_domow = []
self.plansza = None
self.obiekty = None
pygame.sprite.Sprite.__init__(self)
self.rect = pygame.Rect(self.x * WIDTH + MARGIN * self.x + MARGIN, self.y * HEIGHT + MARGIN * self.y, WIDTH,
HEIGHT)
def setObraz(self, obraz):
self.obraz = obraz
def rand_move(self):
rand_int = random.randint(0, 3)
if rand_int == 0:
self.w_lewo()
elif rand_int == 1:
self.w_prawo()
elif rand_int == 2:
self.w_gore()
elif rand_int == 3:
self.w_dol()
def astar_move(self, obiekty):
sciezka = astar.astar(obiekty, self.pozycja,
(random.randrange(15), random.randrange(15)))
print(sciezka)
if sciezka:
for koord in sciezka:
if koord[0] == self.x - 1 and koord[1] == self.y:
self.w_lewo()
elif koord[0] == self.x + 1 and koord[1] == self.y:
self.w_prawo()
elif koord[0] == self.x and koord[1] + 1 == self.y:
self.w_gore()
elif koord[0] == self.x and koord[1] - 1 == self.y:
self.w_dol()
def w_lewo(self):
if self.x > 0:
if self.plansza[self.x - 1, self.y].jestPrzeszkoda is not True:
if self.plansza[self.x - 1, self.y].jestDomem is True:
if [self.x - 1, self.y] not in self.wspolrzedne_odwiedzonych_domow:
self.wspolrzedne_odwiedzonych_domow.append(
[self.x - 1, self.y])
self.zwiekszIloscOdwiedzonychDomow()
if self.ruch == 2:
self.image = pygame.image.load(
'resources/plansza/smieciarka.png')
self.ruch = 1
self.plansza[self.x - 1, self.y].setKolor(BLUE)
for i in range((WIDTH + MARGIN) // 5):
self.rect.x -= 5
self.obraz.blit(self.image, (self.rect.x, self.rect.y))
game.rysowaniePlanszy(self.obiekty)
self.x -= 1
def w_prawo(self):
if self.x < 14:
if self.plansza[self.x + 1, self.y].jestPrzeszkoda is not True:
if self.plansza[self.x + 1, self.y].jestDomem is True:
if [self.x + 1, self.y] not in self.wspolrzedne_odwiedzonych_domow:
self.wspolrzedne_odwiedzonych_domow.append(
[self.x + 1, self.y])
self.zwiekszIloscOdwiedzonychDomow()
if self.ruch == 1:
self.image = pygame.transform.flip(self.image, True, False)
self.ruch = 2
self.plansza[self.x + 1, self.y].setKolor(BLUE)
for i in range((WIDTH + MARGIN) // 5):
self.rect.x += 5
self.obraz.blit(self.image, (self.rect.x, self.rect.y))
game.rysowaniePlanszy(self.obiekty)
self.x += 1
def w_gore(self):
if self.y > 0:
if self.plansza[self.x, self.y - 1].jestPrzeszkoda is not True:
if self.plansza[self.x, self.y - 1].jestDomem is True:
if [self.x, self.y - 1] not in self.wspolrzedne_odwiedzonych_domow:
self.wspolrzedne_odwiedzonych_domow.append(
[self.x, self.y - 1])
self.zwiekszIloscOdwiedzonychDomow()
self.plansza[self.x, self.y - 1].setKolor(BLUE)
for i in range((WIDTH + MARGIN) // 5):
self.rect.y -= 5
self.obraz.blit(self.image, (self.rect.x, self.rect.y))
game.rysowaniePlanszy(self.obiekty)
self.y -= 1
def w_dol(self):
if self.y < 14:
if self.plansza[self.x, self.y + 1].jestPrzeszkoda is not True:
if self.plansza[self.x, self.y + 1].jestDomem is True:
if [self.x, self.y + 1] not in self.wspolrzedne_odwiedzonych_domow:
self.wspolrzedne_odwiedzonych_domow.append(
[self.x, self.y + 1])
self.zwiekszIloscOdwiedzonychDomow()
self.plansza[self.x, self.y + 1].setKolor(BLUE)
for i in range((WIDTH + MARGIN) // 5):
self.rect.y += 5
self.obraz.blit(self.image, (self.rect.x, self.rect.y))
game.rysowaniePlanszy(self.obiekty)
self.y += 1
def dodajPlastik(self, smiec):
self.plastik.append(smiec)
def dodajSzklo(self, smiec):
self.szklo.append(smiec)
def dodajPapier(self, smiec):
self.papier.append(smiec)
def dodajMetal(self, smiec):
self.metal.append(smiec)
def zwiekszIloscOdwiedzonychDomow(self):
self.odwiedzone_domy += 1
def getOdwiedzoneDomy(self):
return self.odwiedzone_domy
def setPlansza(self, plansza):
self.plansza = plansza
def setObiekty(self, obiekty):
self.obiekty = obiekty
class Dom(pygame.sprite.Sprite):
def __init__(self, x, y):
self.x = x
self.y = y
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.__class__
self.rect = pygame.Rect(self.x * WIDTH + MARGIN * self.x + MARGIN, self.y * HEIGHT + MARGIN * self.y + MARGIN,
WIDTH, HEIGHT)
self.smieci = []
def setImage(self, image):
self.image = image
def dodajSmiec(self, smiec):
self.smieci.append(smiec)
def usunSmiec(self, smiec):
self.smieci.remove(smiec)
class Kontener(pygame.sprite.Sprite):
def __init__(self, x, y, typ):
self.x = x
self.y = y
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.__class__
self.rect = pygame.Rect(self.x * WIDTH + MARGIN * self.x + MARGIN, self.y * HEIGHT + MARGIN * self.y + MARGIN,
WIDTH, HEIGHT)
self.smieci = []
self.typ = typ
os.makedirs("resources/smieci w kontenerach/" + self.typ)
def dodajSmiec(self, smiec):
self.smieci.append(smiec)
shutil.copy(smiec, "resources/smieci w kontenerach/" + self.typ)
def setImage(self, image):
self.image = image
class Kratka(pygame.sprite.Sprite):
def __init__(self, poz_x, poz_y):
self.pozX = poz_x
self.pozY = poz_y
self.pozycja = (self.pozX, self.pozY)
self.rodzic = None
self.jestDomem = False
self.jestKontenerem = False
self.jestWysypiskiem = False
self.jestPrzeszkoda = False
self.kolor = GREY
self.obiekt = None
self.g = 0 # Distance to start node
self.h = 0 # Distance to goal node
self.f = 0 # Total cost
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.__class__
self.rect = pygame.Rect(self.pozX * WIDTH + MARGIN * self.pozX + MARGIN,
self.pozY * HEIGHT + MARGIN * self.pozY + MARGIN,
WIDTH, HEIGHT)
# Sort nodes
def __lt__(self, other):
return self.f < other.f
def __repr__(self):
return ('{0}'.format(self.pozycja))
# Compare nodes
def __eq__(self, other):
return True if self.pozycja == other.pozycja else False
def setImage(self, image):
self.image = image
def setRodzic(self, rodzic):
self.rodzic = rodzic
def setObiekt(self, obiekt):
self.obiekt = obiekt
def setJestDomem(self, bool):
self.jestDomem = bool
def setJestSmieciarka(self, bool):
self.jestSmieciarka = bool
def setJestPrzeszkoda(self, bool):
self.jestPrzeszkoda = bool
def setJestKontenerem(self, bool):
self.jestKontenerem = bool
def setJestWysypiskiem(self, bool):
self.jestWysypiskiem = bool
def setKolor(self, kolor):
self.kolor = kolor
def generujWspolrzedneDomow(ilosc_domow):
wspolrzedne_domow = []
r = len(wspolrzedne_domow)
while r < ilosc_domow:
wspolrzedne_domu = []
x = random.randrange(15)
if x < 5:
y = random.randrange(5, 15)
else:
y = random.randrange(15)
wspolrzedne_domu.append(x)
wspolrzedne_domu.append(y)
if 6 <= wspolrzedne_domu[0] <= 7 and 10 <= wspolrzedne_domu[1] <= 11:
continue
if wspolrzedne_domu[0] == 10 and wspolrzedne_domu[1] == 10:
continue
if wspolrzedne_domu not in wspolrzedne_domow:
wspolrzedne_domow.append(wspolrzedne_domu)
r += 1
return wspolrzedne_domow

View File

@ -1,2 +1,58 @@
absl-py==0.9.0
astunparse==1.6.3
autopep8==1.5
cachetools==4.1.0
certifi==2020.4.5.1
chardet==3.0.4
cycler==0.10.0
future==0.18.2
gast==0.3.3
google-auth==1.14.3
google-auth-oauthlib==0.4.1
google-pasta==0.2.0
grpcio==1.29.0
h5py==2.10.0
idna==2.9
importlib-metadata==1.6.0
joblib==0.15.0
Keras==2.3.1
Keras-Applications==1.0.8
Keras-Preprocessing==1.1.2
kiwisolver==1.2.0
mahotas==1.4.9
Markdown==3.2.2
matplotlib==3.2.1
numpy==1.18.0
oauthlib==3.1.0
opencv-python==4.2.0.34
opt-einsum==3.2.1
Pillow==7.1.2
protobuf==3.11.3
pyasn1==0.4.8
pyasn1-modules==0.2.8
pycodestyle==2.5.0
pydotplus==2.0.2
pygame==1.9.6
numpy==1.18.2
pyparsing==2.4.7
PyQt5==5.14.2
python-dateutil==2.8.1
PyYAML==5.3.1
requests==2.23.0
requests-oauthlib==1.3.0
rsa==4.0
scikit-learn==0.23.0
scipy==1.4.1
sip==5.3.0
six==1.14.0
tensorboard==2.2.1
tensorboard-plugin-wit==1.6.0.post3
tensorflow==2.2.0
tensorflow-estimator==2.2.0
termcolor==1.1.0
threadpoolctl==2.0.0
torch==1.5.0
torchvision==0.6.0
urllib3==1.25.9
Werkzeug==1.0.1
wrapt==1.12.1
zipp==3.1.0

BIN
resources/dane/etykiety.h5 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,118 @@
# Sztuczna Inteligencja
**Temat projektu:** Inteligenta Śmieciarka
**Zespół:** Kacper Borkowski, Adam Borowski, Adam Osiowy
**Podprojekt:** Adam Osiowy - *segregator śmieci*
---
## Opis podprojektu:
- w projekcie wykorzystane zostały drzewa decyzyjne jako metoda uczenia
- projekt podzielony jest na 4 pliki
- plik tworzenie_danych_AO.py jest odpowiedzialny za wydobycie z każdego zdjęcia własności i zapis ich do pliku
![4](../screenShots/adamo4.png)
- w pliku uczenie_adamO.py znajdują się funkcje odpowiedzialne za uczenie i testowanie modelu
![5](../screenShots/adamo5.png)
- plik parametry_zdjec.h5 zawiera własności wszystkich zdjęć wykorzystanych w projekcie
- plik etykiety.h5 zawiera odpowiedni typ każdego ze zdjęć (glass,paper,plastic,metal)
---
## Ogólne działanie:
- na początku zbierane są informacje o każdym zdjęciu
```
momenty = wyznaczHuMomenty(zdj)
haralick = wyznaczHaralick(zdj)
histogram = wyznaczHistogram(zdj)
```
- wybrane własności to:
1. Histogram kolorów okreslający rozkład jasności pixeli w każdej komórce na zdjęciu w skali szarości
![6](../screenShots/adamo6.png)
zdjęcie jest przekształcane do przestrzeni barw hsv
po czym wyliczany jest histogram podając do funkcji zdjęcie, kanały (hsv), maskę, podział zdjęcia na 512 przedziałów (8x8x8), zakres każdego kanału
2. Momenty obrazu (Hu Moments) określające kształt obiektu na zdjęciu
![8](../screenShots/adamo8.png)
są średnią ważoną intensywności pikseli obrazu.
Są liczone ze wzoru:
![10](../screenShots/adamo10.png)
gdzie I(x,y) to intensywność pixela w danym punkcie
*Momenty surowe* - informują o intensywności pikseli i ich położeniu na obrazie
*Momenty centralne* - otrzymujemy po odjęciu od momentów surowych środka ciężkości danego kształtu
![11](../screenShots/adamo11.png)
momenty te są niezmienne w wyliczaniu to znaczy że jeśli kształt jest ten sam to nie ważne jest jego położenie na zdjęciu
*Momenty Hu* - to zbiór 7 liczb obliczonych na podstawie momentów centralnych.
Pierwsze 6 momentów są niezmienne dla translacji, skali i rotacji.
Podczas gdy znak siódmej liczby zmienia się wraz z odbiciem kształu (względem osi).
![12](../screenShots/adamo12.png)
3. Tekstura Haralicka określająca nasycenie ilości pixeli w skali szarości
![7](../screenShots/adamo7.png)
"Haralick zasugerował zastosowanie macierzy współwystępowania poziomu szarości (GLCM).
Ta metoda opiera się na połączonych rozkładach prawdopodobieństwa par pikseli.
GLCM pokazuje, jak często każdy poziom szarości występuje w pikselach umieszczonych w ustalonym położeniu
geometrycznym względem siebie, w zależności od poziomu szarości."
![13](../screenShots/adamo13.png)
- własności sa zapisywane jako macierze, ustawiane w szereg jako wiersz i zapisywane do pliku z danymi .h5
```
wiersz = np.hstack([momenty, histogram, haralick])
```
- dane dzielone są losowo na 2 pary, jedna testowa druga treningowa
```
(uczenieDane, testowanieDane, uczenieEtykiety, testowanieEtykiety) =
train_test_split(np.array(dane), np.array(etykiety), test_size=rozmiar_zbioru_testowego)
```
gdzie rozmiar zbioru testowego określony wcześniej na 20%
- tworzony jest estymator
```
rfc = RandomForestClassifier(max_depth=15, n_jobs=4, random_state=1)
```
gdzie n_jobs to ilość wątków, random_state pilnuje aby zbiór był zawsze dzielony tak samo,
a max_depth to maksymalna głebokość każdego drzewa
estymator domyślnie korzysta ze strategii opierającej się o indeks Giniego
```
'indeks Giniego jest to miara która określa jak często losowo wybrany element zostanie błędnie zidentyfikowany'
```
indeks jest obliczany ze wzoru:
![9](../screenShots/adamo9.png)
[przykład](https://www.geeksforgeeks.org/decision-tree-introduction-example/)
- estymator rozpoczyna uczenie korzystając ze zbiorów treningowych
```
rfc.fit(uczenieDane, uczenieEtykiety)
```
- następnie wyliczana jest skuteczność na zbiorach testowych
```
rfc.score(testowanieDane, testowanieEtykiety)
```
---
## Integracja z projektem zespołowym:
- Przy starcie programu estymator rozpoczyna nauke
```
rfc = adamO.rozpocznijUczenie()
```
- Śmieciarka porusza się po domach zbierając z nich śmieci
- Po zebraniu wszystkich śmieci kieruje się na wysypisko
- Każde zdjęcie śmieci jest segregowane z wykorzystaniem funkcji przewidującej typ
```
rodzaj = adamO.przewidz(smiec, rfc)
```
![3](../screenShots/adamo3.png)
- Zdjęcia posegregowanych śmieci umieszczane są w odpowiednich folderach:
![1](../screenShots/adamo1.png)
- Na koniec wyświetlane są losowo wybrane zdjęcia śmieci z kontenerów wraz z informacją o typie ustalonym przez estymator
![2](../screenShots/adamo2.png)
1. górny napis to typ zwrócony przez estymator
2. drugi napis to wartości prawpopodobieństwa z jakim estymator ocenił typ
3. trzeci napis to nazwa zdjęcia
---
## Efekt działania programu w postaci drzewa decyzyjnego:
![10](graph.png)

View File

@ -0,0 +1,68 @@
# Sztuczna Inteligencja
**Temat projektu:** Inteligenta Śmieciarka
**Zespół:** Kacper Borkowski, Adam Borowski, Adam Osiowy
---
## 1. Ogólne działanie:
![gif](../screenShots/gifProjektu.gif)
---
## 2. Struktura katalogów:
![katalogi](../screenShots/strukturaKatalogu.png)
**Resources**:
- _plansza_ - folder zawierający zdjęcia niezbędne do generowania planszy - domy, jezioro, pojemniki, wysypisko,
- _śmieci_ - zawiera podfoldery z klaysifkacją zdjęć śmieci,
- _śmieci w kontenerach_ - folder, który będzie zawierał posegregowane już smieci
**Pliki**:
**[game.py](../../src/game.py)** - plik zawierający całą funkcjonalność projektu:
- główna pętla programu,
- tworzenie planszy,
- tworzenie i usytuowanie obiektów z katalogu [modeli](../../src/modele.py),
- generowanie tekstowej interpretacji zebranej wiedzy
**[main.py](../../src/main.py)** - klasa odpowiedzialna za uruchomienie programu
**[modele.py](../../src/modele.py)** - zawiera klasy aplikacji
**[requirements.txt](../../requirements.txt)** - posiada biblioteki niezbędne do uruchomienia programu, które instalujemy za pomocą poniższego polecenia:
```
pip install -r requirements.txt
```
---
## 3. Opis funkcjonalności programu:
* śmieciarka porusza się w losowy sposób po planszy 15 x 15 (koloruje na niebiesko przebytą trasę)
![ruch śmieciarki](../screenShots/randMove.png)
* domy generowane są losowo na mapie z pominięciem kolizji z innymi obiektami
![generowanie_domów](../screenShots/wspolrzedneDomow.png)
* pozycja wysypiska, przeszkody (jeziorko) i kontenerów jest statyczna
![statyczna_pozycja](../screenShots/statycznaPozycja.png)
* w kontenerach przechowywane będą posegregowane, odpowiednio według kategorii, zdjęcia śmieci
* zdjęcia śmieci będą przydzielane w sposób losowy do każdego z domów na planszy
![losowanie_śmieci](../screenShots/wyborSmieci.png)
* śmieciarka zbiera śmieci po najechaniu na pozycję danego domu
* po każdym uruchomieniu programu tworzona jest struktura katalogów dla posegregowanych śmieci
![tworzenie_struktury](../screenShots/tworzenieStrukturyKatalogow.png)
* śmieciarka sprawdza w każdym ruchu czy nie dojdzie do kolizji z innym obiektem lub nie wyjedzie poza planszę
![sprawdzanie_kolizcji](../screenShots/sprawdzanieKolizji.png)
* po prawej stronie wypisywane są aktualne, najważniejsze informacje
![wiedza](../screenShots/wiedzaPoPrawejStronie.png)
* każdy obiekt na planszy posiada atrybuty odpowiedzalne za
przechowywanie wiedzy o danym obiekcie np.: obiekt śmieciarka przechowuje informacje o odwiedzonych domach
![atrybuty](../screenShots/atrybutySmieciarki.png)

BIN
resources/raporty/graph.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

View File

@ -0,0 +1,54 @@
# Sztuczna Inteligencja
**Temat projektu:** Inteligenta Śmieciarka
**Zespół:** Kacper Borkowski, Adam Borowski, Adam Osiowy
**Podprojekt:** Kacper Borkowski
---
## 1. Model:
![model](../screenShots/kacper1.png)
- Powyższa funkcja tworzy sekwencyjny model sieci neuronowej
- Składa się on z warstw
- Warstwa Conv2D jest to warstwa splotu, stosuje ona filtr na obrazku
- Warstwa Activation jest to warstwa aktywacji wykorzystująca funkcję aktywacji, relu jest to funkcja zwracająca 0 dla x < 0 oraz x dla pozostałych argumentów; softmax to funkcja pozwalająca na poznanie rozkładu prawdopodobieństwa na kategorie
- Warstwa MaxPooling wyciąga największą wartość z wycinka obrazka, w tym przypadku z kawałka 2x2 piksele
- Warstwa Flatten spłaszcza macierz do wektorów
- Warstwa Dense to połączone ze sobą neurony
- Warstwa Dropout przepuszcza część danych, w tym przypadku 50% w celu uniknięcia przeuczenia sieci
---
## 2. Uczenie modelu:
![uczenie](../screenShots/kacper2.png)
- Model uczy się na 1599 zdjęciach śmieci podzielonych na 4 kategorie
- Wszystkie zdjęcia mają rozmiar 299x299 pikseli
- Podczas uczenia zbiór dzielony jest na paczki po 16 elementów
- Zastosowana funkcja straty to categorical_crossentropy ponieważ mamy więcej niż dwie klasy śmieci
---
## 2. Przewidywanie:
![przewidywanie](../screenShots/kacper3.png)
- Obrazki są zamieniane na macierze
- Prediction zawiera rozkład prawdopodobieństwa obrazka na kategorie
- Funkcja zwraca konkretny typ śmiecia w zależności od przewidzianego prawdopodobieństwa
---
## 2. Integracja w projekcie:
![integracja](../screenShots/kacper4.png)
- Podczas wizyty śmieciarki w domu wykonywana jest funkcja przewidzenia kategorii na każdym ze śmieci w danym domu
- Zależnie od wyniku przewidywania śmieć jest umieszczany na odpowiedniej liście śmieci w śmieciarce
- Śmieci z wszystkich list są wyładowywane na wysypisku do kontenerów odpowiadających listom
- Zdjęcia śmieci znajdują się finalnie w posortowanych folderach

View File

@ -0,0 +1,129 @@
# Sztuczna Inteligencja
**Temat projektu:** Inteligenta Śmieciarka
**Zespół:** Kacper Borkowski, Adam Borowski, Adam Osiowy
**Podprojekt:** Adam Borowski
---
## 1. Temat podprojektu:
Celem projektu było utworzenie klasyfikatora rodzajów danych wejściowych(śmieci) na podstawie zdjęć. Do tego celu wykorzystano bibliotekę [PyTorch](https://pytorch.org/docs/stable/index.html). Cały podprojekt opiera się na utworzeniu sieci neuronowej i przetworzeniu inputu przez kolejne jej warstwy.
## 2. Model sieci:
```
class Net(nn.Module): # klasa Net dziedziczaca po klasie bazowej nn.Module
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 71 * 71, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 4)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(x.size(0), 16 * 71 * 71)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
```
- conv1, conv2 warstwy konwolucyjna, rozmiar filtra 5×5, posiadające 3 kanały wejściowe (RGB) i kanały wyjściowe dla następnych warstw
- pool - operacja `max-poolingu` - wyciaganie najwazniejszej informacji z zadanego obszaru obrazu
![model](../screenShots/maxpool.png)
- fc1, fc2, fc3 - warstwy liniowe - `full connection layers` - w odróznieniu od warstw konwolucyjnych, każdy neuron dostaje input o neuronie z poprzedniej warstwy. W warstwie konwolucyjnej neurony wiedzą tylko o określonych neuronach z poprzedniego layera
![model](../screenShots/fc.png)
- metoda `forward` - metoda forward określa cały przepływ(flow) inputu przez warstwy aż do outputu. W pierwszej części tensor danej wejściowej(tensor zdjęcia) przepuszczany jest przez dwie warstwy konwolucyjne i wykonywana jest na nim wcześniej wspomniana operacja `max-poolingu`. W następnej części wypłaszczamy x, wszystkie wymiary przechowujace dane obrazu 16 kanalow o rozmiarach 71×71 rozciągamy jako jeden długi wektor. Na koniec przepuszczamy tensor przez warstwy liniowe i zwracamy output.
## 3. Trening:
```
def train():
net = Net()
trainset = torchvision.datasets.ImageFolder(
root='./resources/zbior_uczacy', transform=transform)
trainloader = torch.utils.data.DataLoader(
trainset, batch_size=1, shuffle=True, num_workers=2)
classes = ('glass', 'metal', 'paper', 'plastic')
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
for epoch in range(10):
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i:
print('[%d, %5d] loss: %.3f' %
(epoch + 1, i + 1, running_loss))
running_loss = 0.0
print('Finished Training')
PATH = './wytrenowaned.pth'
torch.save(net.state_dict(), PATH)
```
- na początku zainicjowano sieć, pobrano zbiór uczący i znormalizowano jego wnętrze, aby każde zdjęcie było pod postacią Tensora(tego wymaga model sieci)
- następnie zdefiniowano kryterium do wyznaczania jakości klasyfikacji zdjęć do klas i wyznaczono optymalizator
- potem wchodzimy do pętli i iterujemy po data secie, pobieramy inputy, czyścimy gradienty z poprzedniej iteracji, za pomocą algorytmu propagacji wstecznej liczymy pochodne z utraconej wartości, wyswietlamy w konsoli loss z danej iteracji,
- następnie zapisujemy wytrenowany model
## 4. Przewidywanie:
```
def predict(img_path):
net = Net()
PATH = './wytrenowaned.pth'
img = Image.open(img_path)
pil_to_tensor = transforms.ToTensor()(img).unsqueeze_(0)
classes = ('glass', 'metal', 'paper', 'plastic')
net.load_state_dict(torch.load(PATH))
net.eval()
outputs = net(pil_to_tensor)
return classes[torch.max(outputs, 1)[1]]
```
- zainicjowano sieć, wczytano ścieżke, przetransformowano argument funkcji(zdjecie) do porządanego formatu
- następnie przekazano tensor jako argument do instancji klasy sieci
- w ostatnim kroku za pomocą funkcji `max` wyciągnięto największą wagę i na jej podstawie rozpoznano klasę
## 5. Integracja w projekcie:
```
for dom in obiekty["domy"]:
if dom.x == pozX and dom.y == pozY:
while dom.smieci:
smiec = dom.smieci.pop(0)
rodzaj = ""
if osoba == 'kacper':
rodzaj = kacper.przewidz(smiec)
elif osoba == 'adamB':
rodzaj = adamB.predict(smiec)
else:
rodzaj = adamO.przewidz(smiec, rfc)
if rodzaj == "paper":
obiekty["smieciarka"].dodajPapier(smiec)
elif rodzaj == "glass":
obiekty["smieciarka"].dodajSzklo(smiec)
elif rodzaj == "metal":
obiekty["smieciarka"].dodajMetal(smiec)
elif rodzaj == "plastic":
obiekty["smieciarka"].dodajPlastik(smiec)
```
- zgodnie z wybraną osobą na starcie wykonywana jest odpowiednia funkcja przewidywania na śmieciach w poszczególnych domach
- finalnie zdjęcia posortowanych śmieci znajdują się w kontenerach(folder `smieci w kontenerach`)

View File

@ -0,0 +1,50 @@
# Raport końcowy
**Temat projektu:** Inteligenta Śmieciarka
**Zespół:** Kacper Borkowski, Adam Borowski, Adam Osiowy
---
## Krótkie wyjaśnienie integracji podprojektów:
Celem projektu było utworzenie inteligentnej śmieciarki. Jej zadaniem było zbieranie śmieci ze wszystkich domów na planszy korzystając z algorytmu _A*_. Docelowo, wybierając jeden z trzech zaimplementowanych przez nas klasyfikatorów, śmieciarka segreguje odpady w kontenerach. Ich zdjęcia trafiają następnie do posortowanego folderu _smieci w kontenerach_.
```
for dom in obiekty["domy"]:
if dom.x == pozX and dom.y == pozY:
while dom.smieci:
smiec = dom.smieci.pop(0)
rodzaj = ""
if osoba == 'kacper':
rodzaj = kacper.przewidz(smiec)
elif osoba == 'adamB':
rodzaj = adamB.predict(smiec)
else:
rodzaj = adamO.przewidz(smiec, rfc)
if rodzaj == "paper":
obiekty["smieciarka"].dodajPapier(smiec)
elif rodzaj == "glass":
obiekty["smieciarka"].dodajSzklo(smiec)
elif rodzaj == "metal":
obiekty["smieciarka"].dodajMetal(smiec)
elif rodzaj == "plastic":
obiekty["smieciarka"].dodajPlastik(smiec)
```
Tworzenie katalogu:
```
# kontenery
if not os.path.exists(smieci_w_kontenerach):
os.makedirs(smieci_w_kontenerach)
else:
for dir in os.listdir(os.getcwd() + "\\" + smieci_w_kontenerach):
files = os.listdir(os.getcwd() + "\\" +
smieci_w_kontenerach + "\\" + dir)
for file in files:
os.remove(os.getcwd() + "\\" +
smieci_w_kontenerach + "\\" + dir + "\\" + file)
```

View File

@ -0,0 +1,69 @@
# Sztuczna Inteligencja
**Temat projektu:** Inteligenta Śmieciarka
**Zespół:** Kacper Borkowski, Adam Borowski, Adam Osiowy
---
## 1. Ogólne działanie:
![gif](../screenShots/route-planning.gif)
- Śmieciarka zaczyna ruch z pozycji (10, 10), po czym odwiedza wszystkie domy,
których współrzędne zostały wylosowane, następnie jedzie na wysypisko do najbliższego kontenera,
po czym wybiera następny najbliższy nieodwiedzony kontener.
- Droga między domami jest wyznaczana przez algorytm A*.
- Każdy następny dom jest najbliższym, jeszcze nieodwiedzonym domem.
---
## 2. Pętla główna strategii przeszukiwania:
![petla](../screenShots/petlaGlowna.png)
- w pętli głównej wykorzystujemy przeszukiwanie grafu (graphsearch)
- tworzymy kolejkę priorytetową, po czym dodajemy do niej bieżący węzeł
- przeprowadzamy test osiągnięcia celu:
- jeżeli cel został osiągnięty, to odtwarzamy ścieżkę przechodząc po rodzicach
- do listy odwiedzonych elementów dodajemy bieżący element
- wybieramy następnika
- następnikowi przypisujemy rodzica
- wyznaczamy priorytet następnika
- dodajemy go do kolejki zgodnie z priorytetem
---
## 3. Funkcja następnika:
![succ](../screenShots/funkcjaNastepnika.png)
gdzie sąsiedzi to:
```
sasiedzi = [(0, 1), (0, -1), (1, 0), (-1, 0)]
```
- następnik jest wyznaczany spośród pól sąsiadujących z danym polem (z pominięciem pól po skosie)
- następnie sprawdzane jest czy nie znajduje się on poza mapą
- potem sprawdzane jest czy wybrany punkt nie jest przeszkodą
---
## 4. Przyjęta heurystyka:
![heurystyka](../screenShots/heurystyka.png)
- Heurystyka to suma odległości Manhattan
---
## 5. Koszt wjechania na pole
![stepcost](../screenShots/stepcost.png)
- Koszt wjechania na pole, na którym jest dom wynosi 3
- Koszt wjechania na pole, które jest wysypiskiem wynosi 2
- Koszt wjechania na pole, które jest kontenerem wynosi 3
- Koszt wjechania na zwyczajne pole wynosi 1
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Some files were not shown because too many files have changed in this diff Show More