Commit 8e93b5cf authored by Karol Actun's avatar Karol Actun
Browse files

first version

parent 6b638d6d
......@@ -6,9 +6,6 @@ seedvalue = 12
## Maximum round number in swarm-world
max_round = 100
# Visualization 1 = On, 0 = Off
visualization = 1
## 1 = Call of particles in randmom order
## 0 = Call of particles in added order in scenario
particle_random_order = True
......@@ -17,6 +14,13 @@ particle_random_order = True
window_size_x = 600
window_size_y = 800
[Visualization]
# Visualization 1 = On, 0 = Off
visualization = 1
#gui
gui = default_gui
[World]
## False = Unlimited world size
## True = limited world size
......@@ -66,7 +70,8 @@ tile_mm_size = 2
#solution= scanning_for_all_aims
## All interfaces
scenario = test_interfaces
#scenario = test_interfaces
scenario = test_interfaces3d
#scenario = hexagon_border
solution = test_all_the_interfaces
from pprint import pprint
from PyQt5.QtGui import QPalette, QColor
from PyQt5.QtWidgets import QVBoxLayout, QPushButton, QFormLayout, QLineEdit, QHBoxLayout, QRadioButton, \
QLabel, QCheckBox, QWidget, QTabWidget, QSlider, QSizePolicy, QStyle, QStyleFactory
from PyQt5.QtCore import Qt
def define_gui(visualization, world):
tabbar = QTabWidget()
tabbar.setMinimumWidth(800)
tabbar.addTab(sim_tab(visualization), "Simulation")
tabbar.addTab(vis_tab(visualization), "Visualization")
set_color(tabbar, QColor(0, 0, 0, 100))
return tabbar
def sim_tab(visualization):
tab = QWidget()
layout = QVBoxLayout()
#rounds per second slider
hbox = QHBoxLayout()
desc = QLabel("rounds per second (%d) : " % visualization.rounds_per_second)
hbox.addWidget(desc)
rps_slider = QSlider(Qt.Horizontal)
rps_slider.setTickInterval(10)
rps_slider.setTickPosition(2)
rps_slider.setMaximum(60)
rps_slider.setMinimum(1)
rps_slider.setSliderPosition(visualization.rounds_per_second)
def set_rps():
visualization.rounds_per_second = rps_slider.value()
desc.setText("rounds per second (%d): " % rps_slider.value())
rps_slider.valueChanged.connect(set_rps)
hbox.addWidget(rps_slider)
layout.addLayout(hbox)
#start stop button
start_stop_button = QPushButton("start")
def start_stop_sim():
visualization.running = not visualization.running
if visualization.running:
start_stop_button.setText("stop")
else:
start_stop_button.setText("start")
start_stop_button.clicked.connect(start_stop_sim)
layout.addWidget(start_stop_button)
tab.setLayout(layout)
return tab
def vis_tab(visualization):
tab = QWidget()
main_layout = QVBoxLayout()
# fov slider
fov_layout = QHBoxLayout()
fov_desc = QLabel("field of view (%d): " % visualization.controller.fov)
fov_layout.addWidget(fov_desc)
fov_slider = QSlider(Qt.Horizontal)
fov_slider.setMinimum(1)
fov_slider.setMaximum(120)
fov_slider.setTickInterval(10)
fov_slider.setTickPosition(2)
fov_slider.setSliderPosition(50)
def set_fov():
visualization.controller.fov = fov_slider.value()
fov_desc.setText("field of view (%d): " % visualization.controller.fov)
visualization.controller.update_window()
fov_slider.valueChanged.connect(set_fov)
fov_layout.addWidget(fov_slider)
main_layout.addLayout(fov_layout)
# projection radio buttons
projection_layout = QHBoxLayout()
projection_layout.addWidget(QLabel("projection: "))
projection_layout.addWidget(QRadioButton("orthografic"))
persproj = QRadioButton("perspective")
def change():
if visualization.controller.projection_type == 'orth':
visualization.controller.projection_type = 'pers'
else:
visualization.controller.projection_type = 'orth'
persproj.setChecked(True)
persproj.toggled.connect(change)
projection_layout.addWidget(persproj)
main_layout.addLayout(projection_layout)
tab.setLayout(main_layout)
return tab
def set_color(widget, color):
widget.setAutoFillBackground(True)
p = widget.palette()
p.setColor(widget.backgroundRole(),color)
widget.setPalette(p)
\ No newline at end of file
......@@ -10,10 +10,17 @@ class ConfigData:
self.seed_value = config.getint("Simulator", "seedvalue")
self.max_round = config.getint("Simulator", "max_round")
self.particle_random_order = config.getboolean("Simulator", "particle_random_order")
self.visualization = config.getint("Simulator", "visualization")
self.window_size_x = config.getint("Simulator", "window_size_x")
self.window_size_y = config.getint("Simulator", "window_size_y")
self.visualization = config.getint("Visualization", "visualization")
try:
self.gui = config.get("Visualization", "gui")
except configparser.NoOptionError as noe:
print("no gui found?")
self.gui = "gui.py"
self.size_x = config.getfloat("World", "size_x")
self.size_y = config.getfloat("World", "size_y")
self.border = config.getboolean("World", "border")
......@@ -34,5 +41,6 @@ class ConfigData:
except configparser.NoOptionError as noe:
self.solution = "solution.py"
self.local_time = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')[:-1]
self.multiple_sim = 0
......@@ -6,8 +6,8 @@ from lib.swarm_sim_header import *
class Marker(matter.Matter):
"""In the classe marker all the methods for the characterstic of a marker is included"""
def __init__(self, world, x, y, color=black, transparency=1):
def __init__(self, world, coordinates, color=black, transparency=1):
"""Initializing the marker constructor"""
super().__init__( world, (x, y), color, transparency, type="marker", mm_size=world.config_data.marker_mm_size)
super().__init__( world, coordinates, color, transparency, type="marker", mm_size=world.config_data.marker_mm_size)
......@@ -16,9 +16,9 @@ from lib.swarm_sim_header import *
class Particle(matter.Matter):
"""In the classe marker all the methods for the characterstic of a marker is included"""
def __init__(self, world, x, y, color=black, transparency=1, particle_counter=0):
def __init__(self, world, coordinates, color=black, transparency=1, particle_counter=0):
"""Initializing the marker constructor"""
super().__init__( world, (x, y), color, transparency,
super().__init__( world, coordinates, color, transparency,
type="particle", mm_size=world.config_data.particle_mm_size)
self.number = particle_counter
self.__isCarried = False
......@@ -84,12 +84,12 @@ class Particle(matter.Matter):
"""
Moves the particle to the given directionection
:param direction: The directionection must be either: E, SE, SW, W, NW, or NE
:param direction: The direction is defined by loaded grid class
:return: True: Success Moving; False: Non moving
"""
direction_coord = get_coordinates_in_direction(self.coordinates, direction)
direction, direction_coord = self.check_within_border(direction, direction_coord)
if check_values_are_coordinates(direction_coord[0], direction_coord[1]):
if grid.is_valid_location(direction_coord):
if self.coordinates in self.world.particle_map_coordinates:
del self.world.particle_map_coordinates[self.coordinates]
......@@ -313,22 +313,22 @@ class Particle(matter.Matter):
logging.info("particle on %s is scanning for %s in %i hops", str(self.coordinates), matter, hop)
if matter == "particles":
scanned_list = global_scanning(self.world.particle_map_coordinates, hop, starting_x, starting_y)
scanned_list = global_scanning(self.world.particle_map_coordinates, hop, self.coordinates)
elif matter == "tiles":
scanned_list = global_scanning(self.world.tile_map_coordinates, hop, starting_x, starting_y)
scanned_list = global_scanning(self.world.tile_map_coordinates, hop, self.coordinates)
elif matter == "markers":
scanned_list = global_scanning(self.world.marker_map_coordinates, hop, starting_x, starting_y)
scanned_list = global_scanning(self.world.marker_map_coordinates, hop, self.coordinates)
else:
scanned_list = global_scanning(self.world.particle_map_coordinates, hop, starting_x, starting_y)
scanned_list = global_scanning(self.world.particle_map_coordinates, hop, self.coordinates)
if scanned_list is not None:
scanned_list.extend(global_scanning(self.world.tile_map_coordinates, hop, starting_x, starting_y))
scanned_list.extend(global_scanning(self.world.marker_map_coordinates, hop, starting_x, starting_y))
scanned_list.extend(global_scanning(self.world.tile_map_coordinates, hop, self.coordinates))
scanned_list.extend(global_scanning(self.world.marker_map_coordinates, hop, self.coordinates))
else:
scanned_list = global_scanning(self.world.tile_map_coordinates, hop, starting_x, starting_y)
scanned_list = global_scanning(self.world.tile_map_coordinates, hop, self.coordinates)
if scanned_list is not None:
scanned_list.extend(global_scanning(self.world.marker_map_coordinates, hop, starting_x, starting_y))
scanned_list.extend(global_scanning(self.world.marker_map_coordinates, hop, self.coordinates))
else:
scanned_list = global_scanning(self.world.marker_map_coordinates, hop, starting_x, starting_y)
scanned_list = global_scanning(self.world.marker_map_coordinates, hop, self.coordinates)
if scanned_list is not None:
return scanned_list
else:
......@@ -470,9 +470,9 @@ class Particle(matter.Matter):
:return: New Tile or False
"""
logging.info("Going to create a tile on position %s", str(self.coordinates))
new_tile = self.world.add_tile(self.coordinates[0], self.coordinates[1], color, transparency)
new_tile = self.world.add_tile(self.coordinates, color, transparency)
if new_tile:
self.world.tile_map_coordinates[self.coordinates[0], self.coordinates[1]].created = True
self.world.tile_map_coordinates[self.coordinates].created = True
self.csv_particle_writer.write_particle(tile_created=1)
self.world.csv_round.update_tiles_num(len(self.world.get_tiles_list()))
self.world.csv_round.update_metrics( tile_created=1)
......@@ -489,11 +489,11 @@ class Particle(matter.Matter):
"""
logging.info("particle with id %s is", self.get_id())
logging.info("Going to create a tile in %s ", str(direction) )
if direction != None:
if direction is not None:
coordinates = get_coordinates_in_direction(self.coordinates, direction)
new_tile = self.world.add_tile(coordinates[0], coordinates[1], color, transparency)
new_tile = self.world.add_tile(coordinates, color, transparency)
if new_tile:
self.world.tile_map_coordinates[coordinates[0], coordinates[1]].created = True
self.world.tile_map_coordinates[coordinates].created = True
logging.info("Tile is created")
self.world.new_tile_flag = True
self.csv_particle_writer.write_particle(tile_created=1)
......@@ -506,22 +506,20 @@ class Particle(matter.Matter):
logging.info("Not created tile ")
return False
def create_tile_on(self, x=None, y=None, color=gray, transparency=1):
def create_tile_on(self, coordinates=None, color=gray, transparency=1):
"""
Creates a tile either on a given x,y coordinates
:param x: x coordinate
:param y: y coordinate
:param coordinates: the coordinates
:return: New Tile or False
"""
logging.info("particle with id %s is", self.get_id())
if x is not None and y is not None:
coordinates = (x, y)
if check_values_are_coordinates(x,y):
if coordinates is not None:
if grid.is_valid_location(coordinates):
logging.info("Going to create a tile on position \(%i , %i\)", x,y )
if self.world.add_tile(coordinates[0], coordinates[1], color, transparency) == True:
self.world.tile_map_coordinates[coordinates[0], coordinates[1]].created = True
if self.world.add_tile(coordinates, color, transparency):
self.world.tile_map_coordinates[coordinates, coordinates[1]].created = True
self.world.new_tile_flag = True
self.csv_particle_writer.write_particle(tile_created=1)
self.world.csv_round.update_tiles_num(len(self.world.get_tiles_list()) )
......@@ -667,7 +665,7 @@ class Particle(matter.Matter):
"""
Takes a tile that is in a given directionection
:param direction: The directionection on which the tile should be taken. Options: E, SE, SW, W, NW, NE,
:param direction: The direction on which the tile should be taken.
:return: True: successful taken; False: unsuccessful taken
"""
if self.carried_particle is None and self.carried_tile is None:
......@@ -690,17 +688,16 @@ class Particle(matter.Matter):
logging.info("Tile cannot taken because particle is carrieng either a tile or a particle")
return False
def take_tile_on(self, x=None, y=None):
def take_tile_on(self, coordinates):
"""
Takes a tile that is in a given directionection
:param x: x coordinate
:param y: y coordinate
:param coordinates
:return: True: successful taken; False: unsuccessful taken
"""
if self.carried_particle is None and self.carried_tile is None:
if check_values_are_coordinates(x, y):
coordinates = (x, y)
if grid.is_valid_location(coordinates):
if coordinates in self.world.tile_map_coordinates:
self.carried_tile = self.world.tile_map_coordinates[coordinates]
logging.info("Tile with tile id %s is in the world", str(self.carried_tile.get_id()))
......@@ -771,16 +768,14 @@ class Particle(matter.Matter):
logging.info("No tile taken for dropping")
return False
def drop_tile_on(self, x=None, y=None):
def drop_tile_on(self, coordinates):
"""
Drops the taken tile on a given directionection
:param x: x coordinate
:param y: y coordinate
:param coordinates
"""
if self.carried_tile is not None:
if check_values_are_coordinates(x, y):
coordinates = (x, y)
if grid.is_valid_location(coordinates):
if coordinates not in self.world.get_tile_map_coordinates():
try: # cher: insert so to overcome the AttributeError
self.carried_tile.drop_me(coordinates)
......@@ -857,8 +852,7 @@ class Particle(matter.Matter):
"""
coordinates = (0, 0)
if x is not None and y is not None:
if check_values_are_coordinates(x, y):
coordinates = (x, y)
if grid.is_valid_location(coordinates):
logging.info("Going to create a particle on position %s", str(coordinates))
new_particle = self.world.add_particle(coordinates[0], coordinates[1], color, transparency)
if new_particle:
......@@ -926,17 +920,15 @@ class Particle(matter.Matter):
logging.info("Could not delet particle on coordinates %s", str(coordinates))
return False
def delete_particle_on(self, x=None, y=None):
def delete_particle_on(self, coordinates=None):
"""
Deletes a particle either on a given x,y coordinates
:param x: x coordinate
:param y: y coordinate
:param coordinates
:return: True: Deleting successful; False: Deleting unsuccessful
"""
if x is not None and y is not None:
if check_values_are_coordinates(x, y):
coordinates = (x, y)
if coordinates is not None:
if grid.is_valid_location(coordinates):
if self.world.remove_particle_on(coordinates):
logging.info("Deleted particle with particle on coordinates %s", str(coordinates))
self.csv_particle_writer.write_particle(particle_deleted=1)
......@@ -1027,7 +1019,7 @@ class Particle(matter.Matter):
logging.info("particle cannot be taken")
return False
def take_particle_on(self, x=None, y=None):
def take_particle_on(self, coordinates):
"""
Takes the particle on the given coordinate if it is not taken
......@@ -1036,8 +1028,7 @@ class Particle(matter.Matter):
:return: True: Successful taken; False: Cannot be taken or wrong Coordinates
"""
if self.carried_particle is None and self.carried_tile is None:
if check_values_are_coordinates(x, y):
coordinates = (x, y)
if grid.is_valid_location(coordinates):
if coordinates in self.world.particle_map_coordinates:
self.carried_particle = self.world.particle_map_coordinates[coordinates]
logging.info("Particle with id %s is in the world", str(self.carried_particle.get_id()))
......@@ -1107,15 +1098,14 @@ class Particle(matter.Matter):
logging.info("No particle taken to drop")
return False
def drop_particle_on(self, x=None, y=None):
def drop_particle_on(self, coordinates=None):
"""
Drops the particle tile on a given x and y coordination
:param x: x coordinate
:param y: y coordinate
"""
if self.carried_particle is not None and x is not None and y is not None and check_values_are_coordinates(x, y):
coordinates = (x, y)
if self.carried_particle is not None and coordinates is not None and grid.is_valid_location(coordinates):
if coordinates not in self.world.particle_map_coordinates:
try: # cher: insert so to overcome the AttributeError
self.carried_particle.drop_me(coordinates)
......@@ -1143,7 +1133,7 @@ class Particle(matter.Matter):
:param new_coordinates: new coorindation points
:return: None
"""
if check_values_are_coordinates(new_coordinates[0], new_coordinates[1]):
if grid.is_valid_location(new_coordinates):
particle.coordinates = new_coordinates
self.particle_map_coordinates[new_coordinates] = particle
return True
......@@ -1190,7 +1180,7 @@ class Particle(matter.Matter):
logging.info("Not created marker on coordinates %s", str(coordinates))
return False
def create_marker_on(self, x=None, y=None, color=black, transparency=1):
def create_marker_on(self, coordinates=None, color=black, transparency=1):
"""
Creates a marker either on a given x,y coordinates
......@@ -1199,16 +1189,14 @@ class Particle(matter.Matter):
:return: New marker or False
"""
coordinates = (0, 0)
if x is not None and y is not None:
if check_values_are_coordinates(x, y):
coordinates = (x, y)
if coordinates is not None:
if grid.is_valid_location(coordinates):
logging.info("Going to create a marker on position %s", str(coordinates))
new_marker = self.world.add_marker(coordinates[0], coordinates[1], color, transparency)
if new_marker:
logging.info("Created marker on coordinates %s", str(coordinates))
self.world.csv_round.update_markers_num(len(self.world.get_marker_list()))
self.world.csv_round.update_metrics( marker_created=1)
self.world.csv_round.update_metrics(marker_created=1)
return new_marker
else:
return False
......@@ -1270,17 +1258,15 @@ class Particle(matter.Matter):
logging.info("Could not delet marker on coordinates %s", str(coordinates))
return False
def delete_marker_on(self, x=None, y=None):
def delete_marker_on(self, coordinates=None):
"""
Deletes a particle either on a given x,y coordinates
:param x: x coordinate
:param y: y coordinate
:param coordinates: the coordinates
:return: True: Deleting successful; False: Deleting unsuccessful
"""
if x is not None and y is not None:
if check_values_are_coordinates(x, y):
coordinates = (x, y)
if coordinates is not None:
if grid.is_valid_location(coordinates):
if self.world.remove_marker_on(coordinates):
logging.info("Deleted marker oords %s", str(coordinates))
self.csv_particle_writer.write_particle(marker_deleted=1)
......
......@@ -2,6 +2,8 @@ import math
import random
from enum import Enum
from lib.visualization.grid_models import CubicGrid
class Colors(Enum):
black = 1
......@@ -56,6 +58,9 @@ x_offset = [0.5, 1, 0.5, -0.5, -1, -0.5 ]
y_offset = [ 1, 0, -1, -1, 0, 1]
grid = CubicGrid(5)
def direction_number_to_string(direction):
"""
:param direction: the direction that should get converted to a string
......@@ -85,28 +90,6 @@ def direction_in_range(direction):
return direction % 6
def check_values_are_coordinates(coordinates_x, coordinates_y):
"""
Checks if the given coordinates are matching the
hexagon coordinates
:param coordinates_x: proposed x coordinate
:param coordinates_y: proposed y coordinate
:return: True: Correct x and y coordinates; False: Incorrect coordinates
"""
if (coordinates_x / 0.5) % 2 == 0:
if coordinates_y % 2 != 0:
return False
else:
return True
else:
if coordinates_y % 2 == 0:
return False
else:
return True
def coordinates_to_sim(coordinates):
return coordinates[0], coordinates[1] * math.sqrt(3 / 4)
......@@ -123,40 +106,29 @@ def get_coordinates_in_direction(coordinates, direction):
:param direction: The direction. Options: E, SE, SW, W, NW, or NE
:return: The coordinaiton of the pointed directions
"""
return coordinates[0] + x_offset[direction], coordinates[1] + y_offset[direction]
return coordinates[0] + direction[0], coordinates[1] + direction[1], coordinates[2] + direction[2]
def global_scanning(matter_map_coordinates_dict, hop, starting_x, starting_y):
def global_scanning(matter_map_coordinates_dict, hop, coordinates):
hop_list = []
if (hop / 2 + starting_x, hop + starting_y) in matter_map_coordinates_dict:
hop_list.append(matter_map_coordinates_dict[(hop / 2 + starting_x, hop + starting_y)])
if (hop + starting_x, starting_y) in matter_map_coordinates_dict:
hop_list.append(matter_map_coordinates_dict[(hop + starting_x, starting_y)])
if (hop / 2 + starting_x, -hop + starting_y) in matter_map_coordinates_dict:
hop_list.append(matter_map_coordinates_dict[(hop / 2 + starting_x, -hop + starting_y)])
if (-hop / 2 + starting_x, -hop + starting_y) in matter_map_coordinates_dict:
hop_list.append(matter_map_coordinates_dict[(-hop / 2 + starting_x, -hop + starting_y)])
if (-hop + starting_x, starting_y) in matter_map_coordinates_dict:
hop_list.append(matter_map_coordinates_dict[(-hop + starting_x, starting_y)])
if (-hop / 2 + starting_x, hop + starting_y) in matter_map_coordinates_dict:
hop_list.append(matter_map_coordinates_dict[(-hop / 2 + starting_x, hop + starting_y)])
directions = list(grid.get_directions_dictionary().values())
def mult(a, s):
return a[0]*s, a[1]*s, a[2]*s
for d in directions:
check_coords = get_coordinates_in_direction(coordinates, d)
if check_coords in matter_map_coordinates_dict:
hop_list.append(matter_map_coordinates_dict[check_coords])
for i in range(1, hop):
if (-hop / 2 + i + starting_x, hop + starting_y) in matter_map_coordinates_dict:
hop_list.append(matter_map_coordinates_dict[(-hop / 2 + i + starting_x, hop + starting_y)])
if (hop / 2 + (0.5 * i) + starting_x, hop - i + starting_y) in matter_map_coordinates_dict:
hop_list.append(
matter_map_coordinates_dict[(hop / 2 + (0.5 * i) + starting_x, hop - i + starting_y)])
if (hop / 2 + (0.5 * i) + starting_x, -hop + i + starting_y) in matter_map_coordinates_dict:
hop_list.append(
matter_map_coordinates_dict[(hop / 2 + (0.5 * i) + starting_x, -hop + i + starting_y)])
if (-hop / 2 + i + starting_x, -hop + starting_y) in matter_map_coordinates_dict:
hop_list.append(matter_map_coordinates_dict[(-hop / 2 + i + starting_x, -hop + starting_y)])
if (-hop / 2 - (0.5 * i) + starting_x, -hop + i + starting_y) in matter_map_coordinates_dict:
hop_list.append(
matter_map_coordinates_dict[(-hop / 2 - (0.5 * i) + starting_x, -hop + i + starting_y)])
if (-hop / 2 - (0.5 * i) + starting_x, hop - i + starting_y) in matter_map_coordinates_dict:
hop_list.append(
matter_map_coordinates_dict[(-hop / 2 - (0.5 * i) + starting_x, hop - i + starting_y)])
for d in directions:
check_coords = get_coordinates_in_direction(coordinates, mult(d,i))
if check_coords in matter_map_coordinates_dict:
hop_list.append(matter_map_coordinates_dict[check_coords])
return hop_list
......@@ -176,16 +148,24 @@ def generating_random_spraded_particles (world, max_size_particle):
print("Max Size of created Particle", len(world.particles))
def create_particle_in_line(world, max_size_particle, start_coordinates):
if start_coordinates[0] % 1 != 0:
start_i = int(start_coordinates[0] - 0.5)
for i in range(start_i, start_i+max_size_particle):
world.add_particle(i + 1.5, start_coordinates[1])
def create_particle_in_line(world, max_size_particle, start_coordinates, direction = None):
else:
for