Commit 43a52113 authored by Pinon Gregory's avatar Pinon Gregory 🦉
Browse files

ajout .py serv notif

parent ef46049e
class PriorityQueue(object):
"""
Priority Queue
The priority object is the one with the lowest priority
"""
def __init__(self):
self.queue = []
self.priority = []
def __str__(self):
return ' '.join([str(i) for i in self.queue])
def empty(self):
""" Checks if the queue is empty
Returns
-------
bool
True if the queue is empty, false otherwise.
"""
return len(self.queue) == 0
def put(self, data, priority):
""" Inserts an element in the queue
Parameters
----------
data : object
data wanted to be inserted in the queue.
priority : float
priority of the data.
Returns
-------
None.
"""
self.priority.append(priority)
self.priority = sorted(self.priority)
index = self.priority.index(priority)
self.queue = self.queue[:index] + [data] + self.queue[index:]
# for popping an element based on Priority
def get(self):
""" Pops the priority object
Returns
-------
result : object
the priority object.
"""
result = self.queue[0]
self.queue = self.queue[1:]
return result
# -*- coding: utf-8 -*-
"""
Compare simplest and shortest path
"""
def compare_path(duration_simplest, duration_short, profil) :
"""Compares two paths and theire duration,
according to the patien's profil, choose the best way
Parameters
----------
duration_simplest : int
time of the simplest path.
duration_short : int
time of the shortest path.
profil : [int]
profile of the patient.
Returns
-------
bool
true if the simplest is chosen, false if it's the shortest.
"""
simplest_chosen = False
if duration_short/duration_simplest < (5-profil[3])/5 :
simplest_chosen = True
return simplest_chosen
# -*- coding: utf-8 -*-
"""
Used to test
"""
import json
import shortest as sh
import instructions as inst
# Not the right format
def exemple_mat(name_file) :
"""Creates a matrix which is gonna be used as an example for testing
Parameters
----------
name_file : string
name where the matrix is going to write the data.
Returns
-------
None.
"""
mat = [[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[-1,0,0,0,-1,0,0,0,0,-1],
[-1,0,0,0,-1,0,0,0,0,-1],
[-1,-1,1,1,-1,-1,1,1,-1,-1],
[1,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,1],
[-1,1,1,-1,-1,-1,1,1,-1,-1],
[-1,0,0,-1,0,0,0,0,0,-1],
[-1,0,0,-1,0,0,0,0,0,-1],
[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]]
with open(name_file,'w') as file :
json.dump(mat,file)
def exemple_shortest_path():
"""Creates a matrix and calculates its shortest path
between start and destination
Returns
-------
None.
"""
maze = [[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
[-1, 0, 0, 0, -1, 0, 0, 0, 0, -1],
[-1, 0, 0, 0, -1, 0, 0, 0, 0, -1],
[-1, -1, 1, 1, -1, -1, 1, 1, -1, -1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[-1, 1, 1, -1, -1, -1, 1, 1, -1, -1],
[-1, 0, 0, -1, 0, 0, 0, 0, 0, -1],
[-1, 0, 0, -1, 0, 0, 0, 0, 0, -1],
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1]]
start = (1, 2)
end = (8, 8)
path = sh.shortest(maze, start, end)
print(path)
def exemple_path_to_instruc():
"""Creates a matrix, calculates its shortest path
then calculate its itinerary
Returns
-------
None.
"""
maze = [[-1, -1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 3, 0],
[0, 0, 0, 0, -1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
start = (1, 1)
end = (7, 6)
path = sh.shortest(maze, start, end)
print(path)
instructions = inst.path_to_instruction(path, 10, maze)
print(instructions)
import shortest as sh
"""
Don't touch -> not in the needs
"""
def same_floor(room1, room2, rooms) :
if rooms[room1]["floor"] == rooms[room1]["floor"] :
return True
else :
return False
def case_different_floors(depart_room, dest_room, rooms) :
(dest_x, dest_y) = rooms[depart_room]["coord"]
()
(dest_room_x, dest_room_y) = rooms[dest_room]["coord"]
# shortest_path_1 = sh.astar(mat, (start_x, start_y), (dest_x, dest_y))
# shortest_path_2 = sh.astar(mat, (start_x, start_y), (dest_room_x, dest_room_y))
return "TODO"
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Management of obstacles, and instruction
"""
from enum import Enum
class Difficulty(Enum):
"""
Enum of the different difficulty, obstacle
"""
DEFAULT = 0 # no obstacle
DOOR = 1
STAIR = 2
LIFT = 3
WALL = -1
ROOM = 4
class Instruction(Enum):
"""
Enum with the different instructions for the route
"""
DemiTour = 0
DescendreAscenseur = 1 # TODO when adding floor gestion
DescendreEscalier = 2 # TODO when adding floor gestion
Droit = 3
Droite90 = 4
Gauche90 = 5
Droite45 = 6
Gauche45 = 7
MonterAscenseur = 8 # TODO when adding floor gestion
MonterEscalier = 9 # TODO when adding floor gestion
Porte = 10
Fin = 11
# -*- coding: utf-8 -*-
"""
Management of obstacles, and instruction
"""
from numpy import arccos, sqrt, pi
from infos import Difficulty, Instruction
def calculation_angle(coord_p, coord, coord_n) :
""" Calculates an angle between 3 points
Parameters
----------
coord_p : (int, int)
coordinates of the previous point.
coord : (int, int)
coordinates of the current point.
coord_n : TYPE
coordinates of the next point.
Returns
-------
float
angle between the two vectors create by the points.
"""
vector_u = (coord[0] - coord_p[0], coord[1] - coord_p[1])
vector_v = (coord_n[0] - coord[0], coord_n[1] - coord[1])
prod_scal = vector_u[0] * vector_v[0] + vector_u[1] * vector_v[1]
magnitude_u = sqrt(vector_u[0]**2 + vector_u[1] **2)
magnitude_v = sqrt(vector_v[0]**2 + vector_v[1]**2)
sign = (vector_u[0] * vector_v[1] - vector_v[0] *vector_u[1] )
if sign > 0 :
return arccos(prod_scal/ (magnitude_u * magnitude_v) ) * 180 / pi
else :
return - arccos(prod_scal/ (magnitude_u * magnitude_v) ) * 180 / pi
def first_instruction(patient_north, building_north, patient_pos, next_point) :
""" Return the first instruction of the path
Parameters
----------
patient_north : float
orientation of the patient in function of the north.
building_north : float
orientation of the north according to the matrix.
patient_pos : (int, int)
position of the patient.
next_point : (int, int)
next point to go.
Returns
-------
Intruction
The first instruction of the path.
"""
coord_p = (patient_pos[0] + 1, patient_pos[1])
orientation = patient_north + building_north
angle = calculation_angle(coord_p, patient_pos, next_point) + orientation
instruction = Instruction.Droit.name
if ( -120 < angle < - 70 ) :
instruction = Instruction.Droite90.name
elif ( 120 > angle > 70) :
instruction = Instruction.Gauche90.name
elif ( -70 < angle < -30) :
instruction = Instruction.Droite45.name
elif ( 70 > angle > 30) :
instruction = Instruction.Gauche45.name
elif ( -120 >= angle >= -190 or 120 <= angle <= 190 ) :
instruction = Instruction.DemiTour.name
return instruction
def path_to_instruction(path, patient_north, building_north, matrix) :
""" Convert a path to a list of instruction
Parameters
----------
path : list of tuple of int
list of coordinates which indicates the path.
patient_north : float
orientation of the phone according to the north (angle)
building_north : float
orientation of the north according to the matrix.
matrix : matrix of int
matrix of the way
Returns
-------
list
Instruction at the coordinates [x,y].
"""
instructions = []
if (path == None) :
return None
first = first_instruction(patient_north, building_north, path[0], path[1])
instructions.append(first)
last_instruction = first
for i in range(1, len(path)-1) :
coord = path[i]
instructions.append((coord[0] * 0.25, coord[1] * 0.25))
if (matrix[coord[0]][coord[1]] == Difficulty.DOOR.value) and (last_instruction != Instruction.Porte.name):
instructions.append(Instruction.Porte.name)
last_instruction = Instruction.Porte.name
elif (matrix[coord[0]][coord[1]] == Difficulty.DEFAULT.value) :
angle = calculation_angle(path[i-1], coord, path[i+1])
if ( -95 < angle < - 80 ) and (last_instruction != Instruction.Droite90.name) :
instructions.append(Instruction.Droite90.name)
last_instruction = Instruction.Droite90.name
elif ( 95 > angle > 80) and (last_instruction != Instruction.Gauche90.name):
instructions.append(Instruction.Gauche90.name)
last_instruction = Instruction.Gauche90.name
elif ( -50 < angle < -40) and (last_instruction != Instruction.Droite45.name):
instructions.append(Instruction.Droite45.name)
last_instruction = Instruction.Droite45.name
elif ( 50 > angle > 40) and (last_instruction != Instruction.Gauche45.name):
instructions.append(Instruction.Gauche45.name)
last_instruction = Instruction.Gauche45.name
elif ( -130 > angle > -190 or 130 < angle < 190 ) and (last_instruction != Instruction.DemiTour.name):
instructions.append(Instruction.DemiTour.name)
last_instruction = Instruction.DemiTour.name
else :
if (last_instruction != Instruction.Droit.name) :
instructions.append(Instruction.Droit.name)
last_instruction = Instruction.Droit.name
instructions.append((path[len(path)-1][0]* 0.25, path[len(path)-1][1] * 0.25))
instructions.append(Instruction.Fin.name)
return instructions
# -*- coding: utf-8 -*-
"""
Loads the necessary data
"""
import json
from infos import Difficulty
def load_matrix(name_file) :
"""Loads a matrix from a json file
Parameters
----------
name_file : string
name of the json file.
Returns
-------
data : mat of int
data from the json converted in correct enum.
"""
with open(name_file) as json_file :
dico = json.load(json_file)
data = dico["columns"]
for i in range(len(data)):
for j in range(len(data[0])) :
if data[i][j] == 0 :
data[i][j] = Difficulty.DEFAULT.value
elif data[i][j] > 0 :
data[i][j] = Difficulty.ROOM.value
elif data[i][j] == -1 :
data[i][j] = Difficulty.WALL.value
elif data[i][j] == -2 :
data[i][j] = Difficulty.DOOR.value
return data
def load_room(name_file) :
"""Loads a dictionnary with the names of the rooms and the coordinates associated
Parameters
----------
name_file : string
name of the json file.
Returns
-------
data : dictionnary
a dictionnary linking a room and its coordinates.
"""
with open(name_file) as json_file :
data = json.load(json_file)
return data
def load_building_north(name_file) :
""" Returns the placement of the north according to the matrix
Parameters
----------
name_file : string
name of the matrix files.
Returns
-------
float
angle/placement of the north according to the matrix.
"""
with open(name_file) as json_file :
data = json.load(json_file)
return data["north_angle"]
def name_to_coord(room_name, rooms_info) :
""" Matchs coordinates to a room
Parameters
----------
room_name : string
name of the room.
rooms_info : dictionnary
dictionnary with all the information of the matrix.
Returns
-------
[int, int]
coordinates of the room.
"""
for features in rooms_info['rooms']['features'] :
if (features["properties"]["room_name"] == room_name) :
return features["properties"]["room_center_case"]
# -*- coding: utf-8 -*-
"""
Main script (used when both shortest and simplest path are calculated)
"""
import sys
import loading as l
import simplest as spl
import shortest as sh
import compare as c
import instructions as inst
def main(start, dest, orientation, profil, name_file_mat, name_file_rooms) :
""" Main script.
Parameters
----------
start : [int, int]
starting point.
dest : string
name of the destination's room.
orientation : float
angle of the patient's phone according to the north.
profil : list of int
profile of the patient.
name_file_mat : string
name of the matrix's file.
name_file_rooms : string
name of the room's name's file.
Returns
-------
Write the instructions in the stdout.
"""
# import and loading of data
mat = l.load_matrix(name_file_mat)
rooms = l.load_room(name_file_rooms)
dest_tab = l.name_to_coord(dest, rooms)
(dest_x, dest_y) = (dest_tab[0], dest_tab[1])
building_north = l.load_building_north(name_file_mat)
# calculate the simplest path
simplest_path = spl.simplest(mat, start, (dest_x, dest_y), profil)
# calculate the shortest path
shortest_path = sh.shortest(mat, start, (dest_x, dest_y))
# according to the profile choose the simplest or the shortest path
simplest_is_chosen = c.compare_path(len(simplest_path), len(shortest_path), profil)
if simplest_is_chosen :
path = simplest_path
else :
path = shortest_path
instructions = inst.path_to_instruction(path, orientation, building_north , mat)
if (instructions == None) :
sys.stdout.write("Pas de chemin possible\n")
else :
sys.stdout.write("@".join(str(x) for x in instructions))
sys.stdout.write("\n")
if __name__ == "__main__":
if len(sys.argv) < 4 :
raise ValueError('\nMinimum arguments : start_x int, start_y int, dest (string), orientation (float) \nFacultatif arguments : profil (list)')
else :
start = (int(float(sys.argv[1])/0.25), int(float(sys.argv[2])/0.25))
dest = sys.argv[3]
orientation = float(sys.argv[4])
if len(sys.argv) < 6 :
profil = [0, 0, 0, 0]
else :
data = ""
for i in range(len(sys.argv[5:])) :
data = data + sys.argv[5+i]
profil = data.strip('][').split(',')
for i in range(len(profil)) :
profil[i] = int(profil[i])
name_file_mat ='./conf/mat.json'
name_file_rooms='./conf/rooms.json'
main(start, dest, orientation, profil, name_file_mat, name_file_rooms)
# -*- coding: utf-8 -*-
"""
Main script called when only using shortest path
"""
import sys
import loading as l
import shortest as