def __init__(self, mechanism: Dict[str, Any], path: Sequence[Sequence[Tuple[float, float]]], parent: QWidget): """Show the information of results, and setup the preview canvas.""" super(PreviewDialog, self).__init__(parent) self.setupUi(self) self.setWindowTitle(f"Preview: {mechanism['Algorithm']} " f"(max {mechanism['last_gen']} generations)") self.setWindowFlags(self.windowFlags() | Qt.WindowMaximizeButtonHint) self.main_splitter.setSizes([400, 150]) self.splitter.setSizes([100, 100, 100]) vpoints = parse_vpoints(mechanism['expression']) vlinks = get_vlinks(vpoints) preview_widget = _DynamicCanvas(mechanism, path, vpoints, vlinks, self) self.left_layout.insertWidget(0, preview_widget) labels = [] for tag, data in chain([('Algorithm', mechanism['Algorithm']), ('time', mechanism['time'])], [(f"P{i}", vpoints[i].c[0]) for i in mechanism['placement']]): if type(data) is tuple: label = f"({data[0]:.02f}, {data[1]:.02f})" elif type(data) is float: label = f"{data:.02f}" else: label = f"{data}" labels.append(f"{tag}: {label}") self.basic_label.setText("\n".join(labels)) # Algorithm information inter = mechanism.get('interrupted', 'N/A') if inter == 'False': inter_icon = "task_completed.png" elif inter == 'N/A': inter_icon = "question.png" else: inter_icon = "interrupted.png" if 'last_fitness' in mechanism: fitness = f"{mechanism['last_fitness']:.06f}" else: fitness = 'N/A' text_list = [ f"Max generation: {mechanism.get('last_gen', 'N/A')}", f"Fitness: {fitness}", f"<img src=\":/icons/{inter_icon}\" width=\"15\"/>" f"Interrupted at: {inter}" ] for k, v in mechanism['settings'].items(): text_list.append(f"{k}: {v}") text = "<br/>".join(text_list) self.algorithm_label.setText( f"<html><head/><body><p>{text}</p></body></html>") # Hardware information self.hardware_label.setText("\n".join([ f"{tag}: {mechanism['hardware_info'][tag]}" for tag in ('os', 'memory', 'cpu') ]))
def __synthesis(self) -> None: """Start synthesis.""" # Check if the amount of the target points are same. length = -1 for path in self.path.values(): if length < 0: length = len(path) if len(path) != length: QMessageBox.warning( self, "Target Error", "The length of target paths should be the same.") return # Get the algorithm type for option, button in self.algorithm_options.items(): if button.isChecked(): algorithm = option break else: raise ValueError("no option") mech = deepcopy(self.mech) mech['expression'] = parse_vpoints(mech.pop('expression', [])) mech['target'] = deepcopy(self.path) def name_in_table(target_name: str) -> int: """Find a target_name and return the row from the table.""" for r in range(self.parameter_list.rowCount()): if self.parameter_list.item(r, 0).text() == target_name: return r return -1 placement: Dict[int, Tuple[float, float, float]] = mech['placement'] for name in placement: row = name_in_table(f"P{name}") placement[name] = ( self.parameter_list.cellWidget(row, 2).value(), self.parameter_list.cellWidget(row, 3).value(), self.parameter_list.cellWidget(row, 4).value(), ) # Start progress dialog dlg = ProgressDialog(algorithm, mech, self.alg_options, self) dlg.show() if not dlg.exec_(): dlg.deleteLater() return mechanisms_plot: List[Dict[str, Any]] = [] for data in dlg.mechanisms: mechanisms_plot.append({ 'time_fitness': data.pop('time_fitness'), 'Algorithm': data['Algorithm'], }) self.mechanism_data.append(data) self.__add_result(data) self.__set_time(dlg.time_spend) self.project_no_save() dlg.deleteLater() dlg = ChartDialog("Convergence Data", mechanisms_plot, self) dlg.show() dlg.exec_() dlg.deleteLater()
def test_case(name: str): expr, inputs = example_list(name) vpoints = parse_vpoints(expr) exprs = t_config(vpoints, inputs) result = expr_solving(exprs, vpoints, {pair: 0. for pair in inputs}) return result[-1]
def test_solving_bfgs(self): """Test Sketch Solve kernel.""" expr, _ = example_list("Jansen's linkage (Single)") system = SolverSystem(parse_vpoints(expr), {(0, 1): 0.}) result = system.solve() x, y = result[7] self.assertAlmostEqual(-43.170055, x, 6) self.assertAlmostEqual(-91.753226, y, 6) # Test if angle value changed system.set_inputs({(0, 1): 45.}) result = system.solve() x, y = result[7] self.assertAlmostEqual(-24.406394, x, 6) self.assertAlmostEqual(-91.789596, y, 6) # Test if link length changed system.set_data({(0, 1): 16.}) result = system.solve() x, y = result[7] self.assertAlmostEqual(-24.117994, x, 6) self.assertAlmostEqual(-91.198072, y, 6)
def __get_path(self, row: int) -> List[List[_Coord]]: """Using result data to generate paths of mechanism.""" result = self.mechanism_data[row] expression: str = result['expression'] same: Dict[int, int] = result['same'] inputs: List[Tuple[_Pair, _Coord]] = result['input'] input_list = [] for (b, d), _ in inputs: for i in range(b): if i in same: b -= 1 for i in range(d): if i in same: d -= 1 input_list.append((b, d)) vpoints = parse_vpoints(expression) expr = t_config(vpoints, input_list) b, d = input_list[0] base_angle = vpoints[b].slope_angle(vpoints[d]) path: List[List[_Coord]] = [[] for _ in range(len(vpoints))] for angle in range(360 + 1): try: result_list = expr_solving( expr, {i: f"P{i}" for i in range(len(vpoints))}, vpoints, [base_angle + angle] + [0] * (len(input_list) - 1) ) except ValueError: nan = float('nan') for i in range(len(vpoints)): path[i].append((nan, nan)) else: for i in range(len(vpoints)): coord = result_list[i] if type(coord[0]) is tuple: path[i].append(cast(_Coord, coord[1])) else: path[i].append(cast(_Coord, coord)) return path
def __get_path(self, row: int) -> List[List[_Coord]]: """Using result data to generate paths of mechanism.""" result = self.mechanism_data[row] expression: str = result['expression'] same: Mapping[int, int] = result['same'] inputs: List[Tuple[_Pair, _Coord]] = result['input'] input_list = [] for (b, d), _ in inputs: for i in range(b): if i in same: b -= 1 for i in range(d): if i in same: d -= 1 input_list.append((b, d)) vpoints = parse_vpoints(expression) expr = t_config(vpoints, input_list) b, d = input_list[0] base_angle = vpoints[b].slope_angle(vpoints[d]) path: List[List[_Coord]] = [[] for _ in range(len(vpoints))] input_pair = {(b, d): 0. for b, d in input_list} for angle in range(360 + 1): input_pair[b, d] = base_angle + angle try: result_list = expr_solving(expr, vpoints, input_pair) except ValueError: nan = float('nan') for i in range(len(vpoints)): path[i].append((nan, nan)) else: for i in range(len(vpoints)): coord = result_list[i] if isinstance(coord[0], tuple): path[i].append(coord[1]) else: path[i].append(coord) return path
def __synthesis(self) -> None: """Start synthesis.""" # Check if the number of target points are same. length = -1 for path in self.path.values(): if length < 0: length = len(path) if len(path) != length: QMessageBox.warning( self, "Target Error", "The length of target paths should be the same.") return # Get the algorithm type if self.type0.isChecked(): type_num = AlgorithmType.RGA elif self.type1.isChecked(): type_num = AlgorithmType.Firefly else: type_num = AlgorithmType.DE # Deep copy it so the pointer will not the same mech_params = deepcopy(self.mech_params) mech_params['Expression'] = parse_vpoints( mech_params.pop('Expression', [])) mech_params['Target'] = deepcopy(self.path) def name_in_table(target_name: str) -> int: """Find a target_name and return the row from the table.""" for r in range(self.parameter_list.rowCount()): if self.parameter_list.item(r, 0).text() == target_name: return r return -1 placement: Dict[int, Tuple[float, float, float]] = mech_params['Placement'] for name in placement: row = name_in_table(f"P{name}") placement[name] = ( self.parameter_list.cellWidget(row, 2).value(), self.parameter_list.cellWidget(row, 3).value(), self.parameter_list.cellWidget(row, 4).value(), ) # Start progress dialog dlg = ProgressDialog(type_num, mech_params, self.alg_options, self) dlg.show() if not dlg.exec_(): dlg.deleteLater() return mechanisms = dlg.mechanisms mechanisms_plot: List[Dict[str, Any]] = [] for data in mechanisms: mechanisms_plot.append({ 'time_fitness': data.pop('time_fitness'), 'Algorithm': data['Algorithm'], }) self.mechanism_data.append(data) self.__add_result(data) self.__set_time(dlg.time_spend) self.workbook_no_save() dlg.deleteLater() dlg = ChartDialog("Convergence Data", mechanisms_plot, self) dlg.show() dlg.exec_() dlg.deleteLater()
def __init__( self, mechanism: Dict[str, Any], path: Sequence[Sequence[_Coord]], monochrome: bool, parent: QWidget ): """Show the information of results, and setup the preview canvas.""" super(PreviewDialog, self).__init__(parent) self.setupUi(self) self.setWindowTitle( f"Preview: {mechanism['algorithm']} " f"(max {mechanism['last_gen']} generations)" ) self.setWindowFlags(self.windowFlags() | Qt.WindowMaximizeButtonHint) for splitter in (self.geo_splitter, self.path_cmp_splitter): splitter.setSizes([400, 150]) self.splitter.setSizes([100, 100, 100]) vpoints = parse_vpoints(mechanism['expression']) vlinks = get_vlinks(vpoints) self.canvas1 = _DynamicCanvas(mechanism, path, vpoints, vlinks, self) self.canvas2 = _DynamicCanvas(mechanism, path, parent=self) for c in (self.canvas1, self.canvas2): c.update_pos.connect(self.__set_mouse_pos) c.set_monochrome_mode(monochrome) self.left_layout.insertWidget(0, self.canvas1) self.path_cmp_layout.addWidget(self.canvas2) self.plot_joint.addItems(f"P{i}" for i in self.canvas2.get_target()) labels = [] for tag, data in chain( [(tag, mechanism.get(tag, 'N/A')) for tag in ( 'algorithm', 'time', 'shape_only', 'wavelet_mode')], [(f"P{i}", (vpoints[i].c[0, 0], vpoints[i].c[0, 1])) for i in mechanism['placement']] ): if type(data) is tuple: label = f"({data[0]:.02f}, {data[1]:.02f})" elif type(data) is float: label = f"{data:.02f}" else: label = f"{data}" labels.append(f"{tag}: {label}") self.basic_label.setText("\n".join(labels)) # Algorithm information inter = mechanism.get('interrupted', 'N/A') if inter == 'False': inter_icon = "task_completed.png" elif inter == 'N/A': inter_icon = "question.png" else: inter_icon = "interrupted.png" if 'last_fitness' in mechanism: fitness = f"{mechanism['last_fitness']:.06f}" else: fitness = 'N/A' text_list = [ f"Max generation: {mechanism.get('last_gen', 'N/A')}", f"Fitness: {fitness}", f"<img src=\":/icons/{inter_icon}\" width=\"15\"/>" f"Interrupted at: {inter}" ] for k, v in mechanism['settings'].items(): text_list.append(f"{k}: {v}") text = "<br/>".join(text_list) self.algorithm_label.setText(f"<html><p>{text}</p></html>") # Hardware information self.hardware_label.setText("\n".join([ f"{tag}: {mechanism['hardware_info'][tag]}" for tag in ('os', 'memory', 'cpu') ]))
from random import random from math import pi, hypot, sin, cos from numpy import array from pyslvs import parse_vpoints, collection_list from pyslvs.optimization import norm_path, norm_pca, FPlanar, NPlanar from pyslvs.metaheuristics import ( algorithm, default, AlgorithmType, Setting, ) from . import TestBase _FOUR_BAR = collection_list("Four bar linkage mechanism") F_PLANAR = FPlanar({ 'expression': parse_vpoints(_FOUR_BAR['expression']), 'input': list(_FOUR_BAR['input']), 'same': _FOUR_BAR['same'], 'placement': { 0: (-70, -70, 10), 1: (70, -70, 10) }, 'target': { 4: [ (60.3, 118.12), (31.02, 115.62), (3.52, 110.62), (-25.77, 104.91), (-81.49, 69.19), (-96.47, 54.906), (-109.34, 35.98),
H = (Total) / (3 * cos(theta) + cos(phiLr) + cos(phiRr)) ## Kinematics ## from pyslvs import ( parse_vpoints, t_config, data_collecting, expr_solving, ) if __name__ == '__main__': vpoints = parse_vpoints( "M[" "J[R, color[green], P[%d, %d], L[ground, link_1]], " "J[R, color[green], P[%d, %d], L[link_1, link_2]], " "J[R, color[green], P[%d, %d], L[link_2, link_3]], " "J[R, color[green], P[%d, %d], L[link_3, link_5]], " "J[R, color[green], P[%d,%d], L[link_4, link_5]], " "J[R, color[green], P[%d, %d], L[ground, link_4]], " "]" % (-0.5 * Total, 0, -0.5 * Total + H * cos(phiLr), H * sin(phiLr), -0.5 * Total + H * cos(phiLr) + H * cos(theta), H * sin(phiLr) + H * sin(theta), -0.5 * Total + H * cos(phiLr) + 2 * H * cos(theta), H * sin(phiLr) + 2 * H * sin(theta), -0.5 * Total + H * cos(phiLr) + 3 * H * cos(theta), H * sin(phiLr) + 3 * H * sin(theta), 0.5 * Total, 0)) if Case == 1: exprs = t_config(vpoints, ((0, 1), (1, 2), (2, 3))) else: theta_3 = 180 - theta_3 exprs = t_config(vpoints, ((0, 1), (1, 2), (5, 4))) mapping = {n: f'P{n}' for n in range(len(vpoints))} data_dict, dof = data_collecting(exprs, mapping, vpoints) pos = expr_solving(exprs, mapping, vpoints, [theta_1, theta_2, theta_3]) position = [[0 for i in range(2)] for j in range(6)]