3d0f9bc8d6
This reverts commit d0a6d2db31
.
391 lines
12 KiB
Python
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)
|