Madra_smieciarka/classes/Garbagetruck.py
2024-05-25 20:34:02 +02:00

391 lines
12 KiB
Python

import math
import heapq
import numpy as np
from joblib import load
import pygame
from classes.Household import *
from classes.Node import *
from classes.Trashcan import Trashcan
from tensorflow.keras.models import load_model
class Garbagetruck:
def __init__(self, mult):
self.mult = mult
self.weather = random.randint(0, 2)
self.season = random.randint(0, 3)
self.daytime = random.randint(0, 3)
self.zapelnienie: int = 1
self.knowledge = [self.season, self.daytime, -1, -1, self.zapelnienie, -1, -1, self.weather]
self.capacity: int = 20
self.trash: list = []
self.trashweight: int = 0
self.image = pygame.image.load("sprites/smieciara.png").convert_alpha()
self.image = pygame.transform.scale(self.image, (mult, mult))
self.position = [3, 3]
self.houses: list = []
self.trashcans: list = []
self.state = None # używane
self.segregation = {"Papier": "paper",
"MetalPlastik": "metals_and_plastics",
"Mixed": "mixed",
"Bio": "bio_waste",
"Szklo": "glass"}
self.route = None # jeszcze nie
self.scanner = load_model("./classes/best_model_newD.h5")
self.planner = None # jeszcze nie
self.driver = load("./classes/drzewo.joblib")
self.orientation = 3 # Niech numery będą tak: N - 0, W - 1, S - 2, E - 3 -- po prostu odwrotnie do zegara
self.runningtime = 0
self.movesequence = []
self.target = None # używane
self.analising = False # używane
def identify(self, trash):
obraz = trash.getImage()
wynik = self.scanner.predict(obraz)
wynik = np.argmax(wynik)
typelist = ["paper", "bio_waste", "mixed", "glass", "metals_and_plastics"]
wynik = typelist[wynik]
trash.setTtype(wynik)
print(f"Prawdziwy typ śmieci: {trash.getRealtype()}\nZidentyfikowany typ śmieci: {trash.getTtype()}")
def getAnalising(self):
return self.analising
def switchAnalising(self):
self.analising = False if self.analising else True
return self
def decision(self, house, trash, can):
knowledge = self.knowledge[:]
knowledge[2] = trash.getTreetype()
knowledge[3] = can.getFull()
knowledge[5] = house.getPaid()
knowledge[6] = house.getLastTaken()
print(knowledge)
if -1 not in knowledge:
return self.driver.predict([knowledge])
else:
print("NIE WIEM, BRAK DANYCH")
def pickTrash(self):
house = self.getState()
can = house.getGarbage()
trashlist = can.getContent()
for trash in trashlist:
self.identify(trash)
if self.trashweight + trash.getWaga() <= self.capacity:
decision = self.decision(house, trash, can)
if decision:
self.addTrash(trash)
can.removeContent(trash)
print(f"Załadunek: {self.trashweight}/{self.capacity}")
self.switchAnalising()
def getState(self):
return self.state
def setMovesequence(self, movesequence):
self.movesequence = movesequence
return self
def setTarget(self):
for place in self.houses:
if place.getFinal():
self.target = place
return
for place in self.trashcans:
if place.getFinal():
self.target = place
return
def getOrientation(self):
return self.orientation
def setOrientation(self, orientation):
self.orientation = orientation % 4
return self
def getRunningtime(self):
return self.runningtime
def setRunningtime(self, runningtime):
self.runningtime = runningtime
return self
def incrRunningtime(self):
self.runningtime += 1
return self
def getTrashcans(self):
return self.trashcans
def setTrashcans(self, others):
self.trashcans = others
return self
def setHouses(self, houses):
self.houses = houses
return self
def getHouses(self):
return self.houses
def getCapacity(self) -> int:
return self.capacity
def getTrash(self) -> list:
return self.trash
def setTrash(self, trash: list) -> None:
self.trash = trash
for item in trash:
self.addTrashweight(item.getWaga)
def addTrash(self, trash: Trash) -> None:
self.trash.append(trash)
self.addTrashweight(trash.getWaga())
def changeZapelnienie(self) -> None:
if self.trashweight < 0.25*self.capacity:
self.zapelnienie = 1
elif self.trashweight < self.capacity:
self.zapelnienie = 2
else:
self.zapelnienie = 0
def getTrashweight(self) -> int:
return self.trashweight
def setTrashweight(self, weight: int) -> None:
self.trashweight = weight
self.changeZapelnienie()
def addTrashweight(self, weight: int) -> None:
self.trashweight += weight
self.changeZapelnienie()
def getImage(self) -> object:
return self.image
def setImage(self, image: object) -> None:
self.image = image
def getPosition(self) -> list:
return self.position
def setPosition(self, position: list) -> object:
self.position = position
return self
def modPosition(self, modX, modY):
x = self.getPosition()[0] + modX
y = self.getPosition()[1] + modY
position = [x, y]
self.setPosition(position)
def getRoute(self):
return self.route
def setRoute(self, route) -> None:
self.route = route
def getScanner(self):
return self.scanner
def setScanner(self, scanner) -> None:
self.route = scanner
def getPlanner(self):
return self.planner
def setPlanner(self, planner) -> None:
self.route = planner
def getDriver(self):
return self.driver
def setDriver(self, driver) -> None:
self.route = driver
def distance(self, object1, object2) -> int:
lok1 = object1.getPosition()
lok2 = object2.getPosition()
dist = abs(lok1[0] - lok2[0]) + abs(lok1[1] - lok2[1])
return dist
def selfdistance(self, target):
if isinstance(target, (Trashcan, Household)):
lok = target.getPosition()
own = self.getPosition()
dist = abs(lok[0] - own[0]) + abs(lok[1] - own[1])
return dist
return math.inf
def scanTile(self):
self.state = None
temp = self.houses[:]
temp.extend(self.trashcans[:])
for loc in temp:
if tuple(self.position) == loc.getPosition():
self.state = loc
return
else:
self.state = False
def printme(self):
x, y = self.getPosition()
return self.mult*x, self.mult*y
def throwGarbage(self):
for item in self.trash:
if item.getTtype() == self.state.getTrashtype():
self.addTrashweight(item.getWeight * (-1))
self.trash.remove(item)
def rotateImage(self, arg):
self.image = pygame.transform.rotate(self.image, 90*arg)
def rotateLeft(self):
self.setOrientation(self.getOrientation()+1)
self.rotateImage(1)
def rotateRight(self):
self.setOrientation(self.getOrientation()-1)
self.rotateImage(-1)
def moveForward(self):
ort = self.orientation
x, y = self.getPosition()
stepX = 0
stepY = 0
if ort == 0 and y != 0:
stepY = -1
elif ort == 1 and x != 0:
stepX = -1
elif ort == 2 and y != 20:
stepY = 1
elif ort == 3 and x != 30:
stepX = 1
self.modPosition(stepX, stepY)
def graphsearch(self):
house_positions = [house.getPosition() for house in self.houses]
cans_positions = [can.getPosition() for can in self.trashcans]
def succ(elem):
def virtRotateLeft(state):
ort = (state[-1] + 1) % 4
result = state[:]
result[-1] = ort
return result
def virtRotateRight(state):
ort = (state[-1] - 1) % 4
result = state[:]
result[-1] = ort
return result
def virtMoveForward(state):
ort = state[-1]
x, y = state[0], state[1]
stepX, stepY = 0, 0
if ort == 0 and y != 0:
stepY = -1
elif ort == 1 and x != 0:
stepX = -1
elif ort == 2 and y != 20:
stepY = 1
elif ort == 3 and x != 30:
stepX = 1
x += stepX
y += stepY
result = [x, y, ort]
return result
op = elem.getState()
forward = {"result": virtMoveForward(op), "action": "F"}
left = {"result": virtRotateLeft(op), "action": "L"}
right = {"result": virtRotateRight(op), "action": "R"}
# print("got children")
return [forward, left, right]
def heuristic(state):
x, y, _ = state
target_x, target_y = self.target.getPosition()
return abs(target_x - x) + abs(target_y - y)
def cost(state):
x, y, _ = state
if (x, y) in house_positions:
return 10
elif (x, y) in cans_positions:
return 5
else:
return 1
fringe = []
explored = []
target = self.target.getPosition()
temp = self.getPosition()[:]
temp.append(self.getOrientation())
initial = Node(temp)
fringe.append((0, initial)) # (priority, node)
while True:
if not fringe:
return False
priority, elem = heapq.heappop(fringe)
virtPos = elem.getState()[:-1]
dist = abs(virtPos[0] - target[0]) + abs(virtPos[1] - target[1])
if dist == 0:
def findWay(node):
temp = node
movelist = []
while temp:
movelist.append(temp.getAction())
temp = temp.getParent()
return movelist
lista = findWay(elem)
result = lista[::-1]
result.pop(0)
return result
explored.append(elem)
suc = succ(elem)
for wynik in suc:
if (wynik['result'] not in [item[1].getState() for item in fringe]
and wynik['result'] not in [item.getState() for item in explored]):
x = (Node(wynik["result"])
.setParent(elem)
.setAction(wynik["action"]))
x.setCost(x.getParent().getCost() + cost(x.getState()))
priority = x.getCost() + heuristic(x.getState())
heapq.heappush(fringe, (priority, x))
def executeMovement(self):
element = self.movesequence.pop(0) if self.movesequence else ""
if element == "L":
self.rotateLeft()
elif element == "R":
self.rotateRight()
elif element == "F":
self.moveForward()
def randomTarget(self):
# wybor1 = random.random()
# if wybor1 < 0.75:
wybor2 = random.choice(self.houses)
while not wybor2.getGarbage().getContent():
wybor2 = random.choice(self.houses)
# else:
# wybor2 = random.choice(self.trashcans)
wybor2.switchFinal()
# print(wybor2)