You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
299 lines
9.0 KiB
299 lines
9.0 KiB
5 years ago
|
import serial
|
||
|
import json
|
||
|
|
||
|
ser = serial.Serial('/dev/ttyACM0',9600)
|
||
|
|
||
|
|
||
|
class Possition:
|
||
|
x = 0
|
||
|
y = 0
|
||
|
limit = 25
|
||
|
|
||
|
|
||
|
class Node:
|
||
|
front = False
|
||
|
right = False
|
||
|
left = False
|
||
|
back = False
|
||
|
directions = {'south': {'Right': 'right', "Left": 'left', 'front': 'front', 'back': 'back'},
|
||
|
'north': {'Right': 'left', "Left": 'right', 'front': 'back', 'back': 'front'},
|
||
|
'west': {'Right': 'back', "Left": 'front', 'front': 'right', 'back': 'left'},
|
||
|
'east': {'Right': 'front', "Left": 'back', 'front': 'left', 'back': 'right'}}
|
||
|
|
||
|
|
||
|
# north
|
||
|
# west east
|
||
|
# south
|
||
|
# matches matrix walls to the ones that the car see: what wall in matrix is cars right wall
|
||
|
def makeNode(self):
|
||
|
a = self.directions[pos.direction]['back']
|
||
|
exec('self.' + a + "=True")
|
||
|
if m.frontDistance > pos.limit:
|
||
|
a = self.directions[pos.direction]['front']
|
||
|
exec('self.' + a + "=True")
|
||
|
if m.leftDistance > pos.limit:
|
||
|
a = self.directions[pos.direction]['Left']
|
||
|
exec('self.' + a + "=True")
|
||
|
if m.rightDistance > pos.limit:
|
||
|
a = self.directions[pos.direction]['Right']
|
||
|
exec('self.' + a + "=True")
|
||
|
print(pos.x, pos.y, self.right, self.front, self.left)
|
||
|
|
||
|
def getCarsRight(self):
|
||
|
a = self.directions[pos.direction]['Right']
|
||
|
ldic = locals()
|
||
|
exec('result=self.' + a, globals(), ldic)
|
||
|
result = ldic['result']
|
||
|
return result
|
||
|
|
||
|
# back
|
||
|
# right left
|
||
|
# front
|
||
|
# |_|
|
||
|
# gives a visual representation of the matrix
|
||
|
|
||
|
def __repr__(self):
|
||
|
x = ""
|
||
|
if self.right:
|
||
|
x = x + " "
|
||
|
else:
|
||
|
x = x + "|"
|
||
|
if self.front:
|
||
|
if self.back:
|
||
|
x = x + " "
|
||
|
else:
|
||
|
x = x + " ̄"
|
||
|
else:
|
||
|
if self.back:
|
||
|
x = x + "__"
|
||
|
else:
|
||
|
x = x + "二"
|
||
|
if self.left:
|
||
|
x = x + " "
|
||
|
else:
|
||
|
x = x + "|"
|
||
|
return x
|
||
|
|
||
|
|
||
|
class Possition:
|
||
|
x = 0
|
||
|
y = 0
|
||
|
limit = 29
|
||
|
oldFrontValue = 0 # !!!se allagh k sthn arxh
|
||
|
oldLeftValue=0
|
||
|
oldRightValue=0
|
||
|
counting = 15
|
||
|
movefinished = True
|
||
|
referencedistance = 0
|
||
|
prevNode = Node()
|
||
|
loopFlag = False
|
||
|
nodeChangedFlag=False
|
||
|
oldDirection = 'south'
|
||
|
direction = 'south'
|
||
|
directions = {'north': {'Right': 'east', "Left": 'west', 'Opposite': 'south'},
|
||
|
'south': {'Right': 'west', "Left": 'east', 'Opposite': 'north'},
|
||
|
'west': {'Right': 'north', "Left": 'south', 'Opposite': 'east'},
|
||
|
'east': {'Right': 'south', "Left": 'north', 'Opposite': 'west'}}
|
||
|
|
||
|
# |
|
||
|
# v
|
||
|
# north
|
||
|
# west east
|
||
|
# south
|
||
|
|
||
|
# changes the direction according to what direction it already was and which way it turned
|
||
|
def setDirection(self, movement):
|
||
|
self.direction = self.directions[self.direction][movement]
|
||
|
|
||
|
# changes the coordinates everytime a Node changes
|
||
|
def moveNode(self):
|
||
|
if self.direction == 'south':
|
||
|
self.y = self.y + 1
|
||
|
elif self.direction == 'north':
|
||
|
self.y = self.y - 1
|
||
|
elif self.direction == 'west':
|
||
|
self.x = self.x - 1
|
||
|
elif self.direction == 'east':
|
||
|
self.x = self.x + 1
|
||
|
|
||
|
# returns the front difference between two jsons
|
||
|
def findDifference(self):
|
||
|
difference = self.oldFrontValue - m.frontDistance
|
||
|
# if the node just got created or if it turned
|
||
|
if self.oldFrontValue is 0 or (self.oldDirection is not self.direction): difference = 0
|
||
|
print('dif', difference)
|
||
|
return difference
|
||
|
|
||
|
def howMuchMoved(self):
|
||
|
self.counting = self.counting + self.findDifference()
|
||
|
self.oldFrontValue = m.frontDistance
|
||
|
self.oldLeftValue = m.leftDistance
|
||
|
self.oldRightValue = m.rightDistance
|
||
|
print('has moved:', self.counting)
|
||
|
|
||
|
# we check if node changed then we change x,y , find out new walls/openings
|
||
|
def checkifNodeChanged(self):
|
||
|
self.nodeChangedFlag = False
|
||
|
if self.counting >= 30 :
|
||
|
flag = True
|
||
|
self.loopFlag = False
|
||
|
self.prevNode = maze[self.y][self.x]
|
||
|
self.moveNode()
|
||
|
maze[self.y][self.x].makeNode()
|
||
|
self.counting = 15
|
||
|
self.nodeChangedFlag=True
|
||
|
|
||
|
|
||
|
class Metrics:
|
||
|
rightDistance = 0
|
||
|
frontDistance = 0
|
||
|
leftDistance = 0
|
||
|
code = 0 # code0:forward() 1:turnR() 2:turnL() 3:turnAround() 3:break()
|
||
|
codedict = {"forward": 0, "turnR": 1, "turnL": 2, "turnAround": 3, "break": 4}
|
||
|
labelRD = "rightDistance"
|
||
|
labelFD = "frontDistance"
|
||
|
labelLD = "leftDistance"
|
||
|
|
||
|
def fromDict(self, d):
|
||
|
self.leftDistance = d[self.labelLD]
|
||
|
self.frontDistance = d[self.labelFD]
|
||
|
self.rightDistance = d[self.labelRD]
|
||
|
|
||
|
def toDict(self):
|
||
|
dict = {}
|
||
|
dict[self.labelRD] = self.rightDistance
|
||
|
dict[self.labelFD] = self.frontDistance
|
||
|
dict[self.labelLD] = self.leftDistance
|
||
|
return dict
|
||
|
|
||
|
def codeToDict(self):
|
||
|
dict = {}
|
||
|
dict["code"] = self.code
|
||
|
return dict
|
||
|
|
||
|
def toString(self):
|
||
|
return (self.labelRD + " " + str(self.rightDistance) + " " + self.labelFD + " " +
|
||
|
str(self.frontDistance) + " " + self.labelLD + " " + str(self.leftDistance))
|
||
|
|
||
|
def readJson(myjson):
|
||
|
x1=myjson.split('{')
|
||
|
x2=x1[1].split('}')
|
||
|
x="{"+x2[0]+"}"
|
||
|
dict = json.loads(x)
|
||
|
m.fromDict(dict)
|
||
|
|
||
|
|
||
|
def createJson():
|
||
|
dict = m.codeToDict()
|
||
|
y = json.dumps(dict)
|
||
|
return y
|
||
|
|
||
|
def ignoreMetrics():
|
||
|
flag=False
|
||
|
if (abs(m.frontDistance-pos.oldFrontValue)>25):
|
||
|
flag=True
|
||
|
if (abs(m.leftDistance-pos.oldLeftValue)>25):
|
||
|
flag=True
|
||
|
if (abs(m.rightDistance-pos.oldRightValue)>25):
|
||
|
flag=True
|
||
|
return flag
|
||
|
|
||
|
|
||
|
# north
|
||
|
# west east
|
||
|
# south
|
||
|
def checkforLoop():
|
||
|
flag = False
|
||
|
if pos.prevNode is not []:
|
||
|
if (pos.prevNode.getCarsRight() is False) and (maze[pos.y][pos.x].getCarsRight() is True):
|
||
|
print("loop")
|
||
|
flag = True
|
||
|
return flag
|
||
|
|
||
|
|
||
|
def moveFinished(lim=0):
|
||
|
flag = False
|
||
|
print(m.code)
|
||
|
# ean perpathse toul 25 ek diesxhse ena node
|
||
|
if m.code is m.codedict["forward"]:
|
||
|
if pos.nodeChangedFlag is True:
|
||
|
flag = True
|
||
|
# ean h palia de3ia timh plhsiazei to mprostino meros
|
||
|
if m.code is m.codedict["turnR"]:
|
||
|
if lim - m.frontDistance < 10:
|
||
|
flag = True
|
||
|
# ean h palia aristerh timh plhsiazei to mprostino meros
|
||
|
if m.code is m.codedict["turnL"]:
|
||
|
if lim - m.frontDistance < 10:
|
||
|
flag = True
|
||
|
# ean h de3ia plhsiazei thn palia aristerh timh
|
||
|
if m.code is m.codedict["turnAround"]:
|
||
|
if lim - m.rightDistance < 3:
|
||
|
flag = True
|
||
|
print('movedf', flag)
|
||
|
return flag
|
||
|
|
||
|
# movement logic: where to go changes direction if needs to and checks if node is changed
|
||
|
def move():
|
||
|
pos.howMuchMoved()
|
||
|
if pos.movefinished is True:
|
||
|
pos.oldDirection = pos.direction
|
||
|
if m.rightDistance > pos.limit:
|
||
|
pos.referencedistance = m.rightDistance
|
||
|
if pos.nodeChangedFlag is True:
|
||
|
#you just changed node so you must turn
|
||
|
if checkforLoop() is True:
|
||
|
m.code = m.codedict["turnR"]
|
||
|
pos.setDirection('Right')
|
||
|
else:
|
||
|
#you have already turned go ahead
|
||
|
m.code = m.codedict["forward"]
|
||
|
elif m.frontDistance > pos.limit:
|
||
|
m.code = m.codedict["forward"]
|
||
|
pos.movefinished = False
|
||
|
elif m.leftDistance > pos.limit:
|
||
|
pos.referencedistance = m.leftDistance
|
||
|
print('lim', pos.referencedistance)
|
||
|
m.code = m.codedict["turnL"]
|
||
|
pos.setDirection('Left')
|
||
|
pos.movefinished = False
|
||
|
else:
|
||
|
m.code = m.codedict["turnAround"]
|
||
|
pos.referencedistance = m.leftDistance
|
||
|
pos.setDirection('Opposite')
|
||
|
pos.movefinished = moveFinished(pos.referencedistance)
|
||
|
pos.checkifNodeChanged()
|
||
|
|
||
|
|
||
|
|
||
|
m=Metrics()
|
||
|
pos = Possition()
|
||
|
h, l = 10, 5
|
||
|
maze = [[[] for x in range(h)] for y in range(l)]
|
||
|
for y in range(l):
|
||
|
for x in range(h):
|
||
|
maze[y][x]=Node()
|
||
|
|
||
|
while True:
|
||
|
try:
|
||
|
ser.flush()
|
||
|
read_serial=ser.readline()
|
||
|
ser.write("a".encode())
|
||
|
print("print",read_serial)
|
||
|
read_serial = read_serial.decode('utf-8')
|
||
|
readJson(read_serial)
|
||
|
if (ignoreMetrics() is True):
|
||
|
print('ignore')
|
||
|
continue
|
||
|
move()
|
||
|
y=createJson()
|
||
|
ser.write(str(y).encode())
|
||
|
f = open('output.txt', 'w', encoding=('utf-8'))
|
||
|
for j in maze:
|
||
|
print(j)
|
||
|
f.write(str(j))
|
||
|
f.write('\n\n')
|
||
|
f.close()
|
||
|
except:
|
||
|
pass
|