def __init_(self, name="Zumo32u4", port="/dev/tty/ACM0"): self.name = name self.max_speed = 100 # This is the maximum speed allowed for the zumo. It works as a percentage self.logger = Logging(f"./logs/{name}") self.connection = ZumoConnection(self.logger, port) self.logger.log_info("Created Zumo32u4 instance") self.sensors = ZumoSensors()
def test_acyclic(self): Logging.enable() self.vertices = { 0: [1], 1: [2, 3], 2: [3], 3: [4, 6], 4: [5, 6], 5: [], 6: [] } self.directed_graph = DirectedGraph(self.vertices) self.assertFalse(self.directed_graph.is_cyclic())
def __init__(self, tuning_parameter_collection, modulator_proxy, generators, height_adapter, sampling_rate, advanced = False): QtGui.QMainWindow.__init__(self) Logging.__init__(self) self.tuning_collection = tuning_parameter_collection # The collection of all stored tuning parameters # self.tuning_parameters = tuning_parameter_collection.tuning_parameters[0] # The current tuning parameters self.modulator_proxy = modulator_proxy self.generators = generators self.generator = None self.height_adapter = height_adapter self.sampling_rate = sampling_rate self.test_height = 0.0 self.calibrate_test_mode = self.CALIBRATE_MODE self.laser_enabled = True self.setupUi(self) # NOTE: Have to manually add button group because pyside-uic fails to compile them self.modulation_buttonGroup = QtGui.QButtonGroup(self) self.modulation_buttonGroup.setExclusive(True) self.modulation_buttonGroup.addButton(self.modulation_radioButton_AM, self.MODULATION_ID_BY_TYPE[ModulationTypes.AM]) self.modulation_buttonGroup.addButton(self.modulation_radioButton_DC, self.MODULATION_ID_BY_TYPE[ModulationTypes.DC]) self.laser_power_buttonGroup = QtGui.QButtonGroup(self) self.laser_power_buttonGroup.setExclusive(True) self.laser_power_buttonGroup.addButton(self.laser_power_radioButton_On, self.LASER_POWER_ON_ID) self.laser_power_buttonGroup.addButton(self.laser_power_radioButton_Off, self.LASER_POWER_OFF_ID) self.generator_list_model = QtGui.QStringListModel() self.generator_list_model.setStringList(sorted(self.generators.keys())) self.calibrations_list_model = TuningParameterListModel(self.tuning_collection) # Set model now so selection model will be ready for signal creation self.calibrations_listview.setModel(self.calibrations_list_model) self.test_height_edit.setText(str(self.test_height)) self.calibrate_test_tab_widget.setCurrentWidget(self.calibrate_test_tab_widget.widget(self.calibrate_test_mode)) self.update_build_parameters() index = self.calibrations_list_model.index(0) self.calibrations_listview.setCurrentIndex(index) # Wait until after connecting signals to connect this model so that signals fire self.pattern_combobox.setModel(self.generator_list_model) self.pattern_combobox.setCurrentIndex(0) self.modulation_radioButton_AM.setChecked(True) self.laser_power_radioButton_On.setChecked(True) self._add_tuning_parameters(0.0) self.set_initial_generator() self.connect_ui_elements() if (not advanced): self.hide_advanced_ui()
def test_cyclic(self): Logging.enable() self.vertices = { 0: [1], 1: [2, 3], 2: [3], 3: [4], 4: [5, 2], 5: [6], 6: [7], 7: [5] } self.directed_graph = DirectedGraph(self.vertices) self.assertTrue(self.directed_graph.is_cyclic())
def test_viztracing_cyclic(self): Logging.enable() self.vertices = {0: [1], 1: [2, 3], 2: [3], 3: [4, 6], 4: [5, 6], 5: [7, 8], 6:[7, 8], 7: [9, 10, 11], 8: [3], 9: [], 10: [11], 11: [12], 12: []} self.directed_graph = DirectedGraph(self.vertices) pt.create_dir_in_user_home(TestDirectedGraph.RESOURCES_PATH) VizTracing.enable( pt.get_dir_in_user_home(TestDirectedGraph.RESOURCES_PATH), self.directed_graph, vertex_states=[ {VizTracing.ACTIVATED: {"fillcolor":"red", "style": "filled"}}, {VizTracing.IN_CYCLE: {"fillcolor":"blue", "style": "filled"}}, {VizTracing.VISISTED: {"fillcolor":"gray", "style": "filled"}}]) self.assertTrue(self.directed_graph.is_cyclic())
def is_cyclic(directed_graph): """ Function that checks whether a directed graph contains a cycle or not Args: directed_graph (DirectedGraph): The directed graph Returns: bool: True if the directed graph contains a cycle, otherwise False """ Logging.log("\nStarting cycle check") traversed_already = dict() in_cycle = {i:False for i in directed_graph.get_vertices().keys()} for label, vertex in directed_graph.get_vertices().items(): if traversed_already.get(label) is None: if is_cyclic_dfs(directed_graph, vertex, traversed_already, in_cycle): return True return False
class Mod: _logger = Logging.get_default_logger() def __init__(self, path, json_object): self.path = path self.__json = json_object self.__manifest_entries = [] @property def path(self): return self.__path @property def name(self): return self.__json['Name'] @property def enabled(self): return self.__json["Enabled"] if 'Enabled' in self.__json else True @property def dll(self): return self.__json["DLL"] if 'DLL' in self.__json else None @property def depends_on(self): return self.__json["DependsOn"] if 'DependsOn' in self.__json else [] @property def optionally_depends_on(self): return self.__json["OptionallyDependsOn"] if 'OptionallyDependsOn' in self.__json else [] @path.setter def path(self, path): self.__path = path @property def manifest_entries(self): return self.__manifest_entries @property def json(self): return self.__json def __repr__(self): return f'Mod [Name - {self.name}] | [Enabled - {self.enabled}]'
def create_sccs_kosaraju_dfs(directed_graph, nontrivial): """ Function that creates a list of strongly connected components according to Kosaraju's algorithm (https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm) with a depth-first-search approach. Args: directed_graph (DirectedGraph): The directed graph for which the SCCS should be calculated nontrivial(bool): If True, only nontrivial sccs will be returned, otherwise all sccs Returns: list(set()) of SCCs: Each SCC is a set of vertices """ Logging.log("\nStarting") stack = [] sccs_trivial, visited = list(), dict() for vertex in directed_graph.get_vertices().keys(): if visited.get(vertex) is None: Logging.log("Vertex {0} not visited, go deep", vertex) kh.fill_order_dfd_sccs(directed_graph, vertex, visited, stack) else: Logging.log("Vertex {0} already visited, skipping", vertex) reversed_graph = get_reversed_graph(directed_graph) visited = dict() for i in reversed(stack): if visited.get(i) is None: sccs_trivial.append(set()) kh.visit_dfs_sccs(reversed_graph, i, visited, sccs_trivial[-1]) if nontrivial: return filter_nontrivial(sccs_trivial, directed_graph) else: return sccs_trivial
from argparse import ArgumentParser from builders.mod_collection_builder import ModCollectionBuilder from features.devUtils import generate_object_type_enum from util.logging import Logging if __name__ == '__main__': Logging.init_logging('./res/config.ini') logger = Logging.get_default_logger() try: parser = ArgumentParser( description='Utility for BattleTech ModTek mods.') parser.add_argument('btpath', metavar='"Battle Tech path"', type=str, help='HBS BattleTech folder') parser.add_argument('modspath', metavar='"ModTek mods path"', type=str, help='ModTek Mods folder') parser.add_argument( '-ot', help='Enumerate distinct object types in the mod collection', action='store_true', default=False, dest='list_object_types') parser.add_argument('-v', help='Validate the mod collection', action='store_true', default=False, dest='validate_mods')
import sys import wave import cue_file as cue_file_mod from audio.drip_detector import DripDetector, VirtualDripDetector from audio.tuning_parameter_file import TuningParameterFileHandler from util.logging import Logging drip_governor = None if TRACE: log_level = 'TRACE' else: log_level = 'INFO' log = Logging(level=log_level) # Parse command line arguments if len(sys.argv) == 4: tuning_filename, wave_file_name, cue_file_name = sys.argv[1:] elif len(sys.argv) == 5: from util.drip_governor import DripGovernor tuning_filename, wave_file_name, cue_file_name, port = sys.argv[1:] drip_governor = DripGovernor(port) print('importing drip gov') else: print("Usage: %s <tuning.dat> <output.wav> <output.cue>" % sys.argv[0]) sys.exit(1) # Loading tuning parameters tuning_collection = TuningParameterFileHandler.read_from_file(tuning_filename)
def __init__(self, tuning_parameter_collection): QtCore.QAbstractListModel.__init__(self) Logging.__init__(self) self._collection = tuning_parameter_collection
class ModCollection: _logger = Logging.get_default_logger() def __init__(self, path): self.path = path self.__mods = [] self.__invalidMods = [] self.__modLoadOrder = [] @property def path(self): return self.__path @property def mods(self): return self.__mods @property def invalid_mods(self): return self.__invalidMods @property def valid_mods(self): return [mod for mod in self.mods if mod.name not in map(lambda d: d[0].name, self.invalid_mods)] @property def mod_load_order(self): return self.__modLoadOrder @path.setter def path(self, path): self.__path = path @property def is_valid(self): return len(self.invalid_mods) == 0 def parse_mods(self): mod_package_paths = filter(lambda d: isdir(join(self.path, d)) and isfile(join(self.path, d, 'mod.json')), os.listdir(self.path)) for mod_package_path in mod_package_paths: self.mods.append(ModBuilder.build_from_definition(join(self.path, mod_package_path))) @staticmethod def validate_mod_configuration(mod): return mod.enabled def validate_mod_dependencies(self, mod): missing_dependencies = [dependency for dependency in mod.depends_on if dependency not in [mod.name for mod in self.mods if mod.name == dependency]] invalid_dependencies = [dependency for dependency in [mod_name for mod_name in mod.depends_on if mod_name not in missing_dependencies] if dependency not in [dependency_mod.name for dependency_mod in self.mods if dependency_mod.name == dependency and self.validate_mod_configuration(dependency_mod) and self.validate_mod_dependencies(dependency_mod)[2] is True]] return missing_dependencies, invalid_dependencies, False if len(missing_dependencies) > 0 or len(invalid_dependencies) > 0 else True def validate_mods(self): for mod in self.mods: missing_dependencies, invalid_dependencies, result = self.validate_mod_dependencies(mod) self.invalid_mods.append((mod, f'Missing dependencies - {missing_dependencies}, invalid dependencies = {invalid_dependencies}')) if result is False else None def build_load_order(self): iteration = 1 mods_to_load = self.valid_mods [self.mod_load_order.append(mod) for mod in mods_to_load if len(mod.depends_on) == 0 and len(mod.optionally_depends_on) == 0] [mods_to_load.remove(mod) for mod in self.mod_load_order] self._logger.info(f'\r\n--Load Order Round {iteration}--\r\n' + '\r\n'.join(map(lambda mod: mod.name, self.mod_load_order))) while len(mods_to_load) > 0: iteration += 1 valid_dependent_mods = [mod for mod in mods_to_load if len([dependency for dependency in mod.depends_on if dependency not in map(lambda mod: mod.name, self.mod_load_order)] ) == 0 and len([optional_dependency for optional_dependency in mod.optionally_depends_on if optional_dependency in map(lambda mod: mod.name, self.valid_mods) and optional_dependency not in map(lambda mod: mod.name, self.mod_load_order)] ) == 0] [self.mod_load_order.append(mod) for mod in valid_dependent_mods] [mods_to_load.remove(mod) for mod in valid_dependent_mods] self._logger.info(f'\r\n--Load Order Round {iteration}--\r\n' + '\r\n'.join(map(lambda mod: mod.name, valid_dependent_mods)))
class Zumo32u4: def __init_(self, name="Zumo32u4", port="/dev/tty/ACM0"): self.name = name self.max_speed = 100 # This is the maximum speed allowed for the zumo. It works as a percentage self.logger = Logging(f"./logs/{name}") self.connection = ZumoConnection(self.logger, port) self.logger.log_info("Created Zumo32u4 instance") self.sensors = ZumoSensors() def _set_right_motor_speed(self, speed): """ Sets the speed of the right motor :param speed: The speed for the motor. Between 0 and 100. Acts as a percentage """ instruction = "Instructions.SET_RIGHT_MOTOR_SPEED" speed = f"{speed};"#This will grab the value instruction = f"{instruction}{speed};" self.connection.send_instruction(instruction) def _set_left_motor_speed(self, speed): """ Sets the speed of the left motor :param speed: The speed for the motor. Between 0 and 100. Acts as a percentage """ instruction = "Instructions.SET_LEFT_MOTOR_SPEED" speed = f"{speed};"#This will grab the value instruction = f"{instruction}{speed};" self.connection.send_instruction(instruction) def move_forward(self, speed): """ Will make the zumo move forward. Does this by taking a value (the speed) and sets both left and right motors to this speed. :param speed: Speed for the zumo. Expected as a float. """ speed = float(speed) if speed > self.max_speed: self.logger.log_warn(f"Received speed of {speed} in move_forward. Rounded down to {self.max_speed}") speed = self.max_speed self._set_left_motor_speed(speed) self._set_right_motor_speed(speed) def move_backward(self, speed): """ Will make the zumo move backward. Does this by taking a value (the speed) and sets both left and right motors to this speed. :param speed: Speed for the zumo, will be taken as a negative value. Expected as a float. """ if speed > self.max_speed: self.logger.log_warn(f"Received speed of {speed} in move_backward. Rounded down to {self.max_speed}") speed = self.max_speed self._set_left_motor_speed(-speed) self._set_right_motor_speed(-speed) def turn_right(self, angle, speed): """ Will make the zumo rotate to the right by moving only the right motor. :param angle: The angle to turn. Taken as an integer between 0 and 360. :param speed: How fast the turn should be completed. Between 0 and 100. """ if angle < 0 or angle > 360: self.logger.log_warn(f"Receieved an angle of {angle} in turn_right. Not valid. Ignoring instruction") def turn_left(self, angle, speed): """ Will make the zumo rotate to the left by moving only the left motor. :param angle: The angle to turn. Taken as an integer between 0 and 360. :param speed: How fast the turn should be completed. Between 0 and 100. """ if angle < 0 or angle > 360: self.logger.log_warn(f"Receieved an angle of {angle} in turn_right. Not valid. Ignoring instruction") pass
def fill_order_dfd_sccs(directed_graph, vertex, visited, stack): """ Function that covers the first part of the algorith by determining the order of vertices, traversing the graph with a depth first search, recursively Args: directed_graph (DirectedGraph): The directed graph vertex: The current vertex visited (dict): A dictionary that maintains whether vertices have been visisted stack (list): stack that will be processed, used to inverse the order """ visited[vertex] = True for head in directed_graph.get_vertices()[vertex].get_heads(): Logging.log("Vertex {0}, head {1} in fill order starting", vertex, head.get_label()) if visited.get(head.get_label()) is None: Logging.log( "Vertex {0}, head {1} not visited, go to fill order rec.", vertex, head.get_label()) Logging.inc_indent() fill_order_dfd_sccs(directed_graph, head.get_label(), visited, stack) Logging.dec_indent() Logging.log("Vertex {0}, head {1} returned from fill order", vertex, head.get_label()) Logging.log("Vertex {0}, head {1} in fill order finished", vertex, head.get_label()) else: Logging.log("Vertex {0}, head {1} already visited, skipping", vertex, head.get_label()) Logging.log("Vertex {0}, head {1} in fill order finished", vertex, head.get_label()) stack = stack.append(vertex)