# HG changeset patch # User lbessard # Date 1220631143 -7200 # Node ID f7df265edd54a32aac257a4504d7ba183c104874 # Parent 4a47ccafbef74c283df683b9de2925a29ecb6a8a Problem with multi-connection on block in LD fixed diff -r 4a47ccafbef7 -r f7df265edd54 PLCGenerator.py --- a/PLCGenerator.py Mon Sep 01 16:31:50 2008 +0200 +++ b/PLCGenerator.py Fri Sep 05 18:12:23 2008 +0200 @@ -672,53 +672,6 @@ if body_type in ["IL","ST"]: self.Program = [(ReIndentText(body_content["value"].gettext(), len(self.CurrentIndent)), (self.TagName, "body", len(self.CurrentIndent)))] - elif body_type == "FBD": - orderedInstances = [] - otherInstances = {"outVariables" : [], "block" : [], "connector" : []} - for instance in body.getcontentInstances(): - if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable, plcopen.fbdObjects_block)): - executionOrderId = instance.getexecutionOrderId() - if executionOrderId > 0: - orderedInstances.append((executionOrderId, instance)) - elif isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)): - otherInstances["outVariables"].append(instance) - elif isinstance(instance, plcopen.fbdObjects_block): - otherInstances["block"].append(instance) - elif isinstance(instance, plcopen.commonObjects_connector): - otherInstances["connector"].append(instance) - orderedInstances.sort() - instances = [instance for (executionOrderId, instance) in orderedInstances] - instances.extend(otherInstances["connector"] + otherInstances["outVariables"] + otherInstances["block"]) - for instance in instances: - if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)): - connections = instance.connectionPointIn.getconnections() - if connections and len(connections) == 1: - expression = self.ComputeFBDExpression(body, connections[0]) - self.Program += [(self.CurrentIndent, ()), - (instance.getexpression(), (self.TagName, "io_variable", instance.getlocalId(), "expression")), - (" := ", ())] - self.Program += expression - self.Program += [(";\n", ())] - elif isinstance(instance, plcopen.fbdObjects_block): - block_type = instance.gettypeName() - self.ParentGenerator.GeneratePouProgram(block_type) - block_infos = self.GetBlockType(block_type) - block_infos["generate"](self, instance, body, None) - elif isinstance(instance, plcopen.commonObjects_connector): - connector = instance.getname() - if self.ComputedConnectors.get(connector, None): - continue - connections = instance.connectionPointIn.getconnections() - if connections and len(connections) == 1: - self.ComputedConnectors[connector] = self.ComputeFBDExpression(body, connections[0]) - elif body_type == "LD": - for instance in body.getcontentInstances(): - if isinstance(instance, plcopen.ldObjects_coil): - expression = self.ComputeLDExpression(body, instance.connectionPointIn.getconnections()) - coil_info = (self.TagName, "coil", instance.getlocalId()) - variable = self.ExtractModifier(instance, [(instance.getvariable(), coil_info + ("reference",))], coil_info) - self.Program += [(self.CurrentIndent, ())] + variable - self.Program += [(" := ", ())] + expression + [(";\n", ())] elif body_type == "SFC": self.IndentRight() for instance in body.getcontentInstances(): @@ -739,33 +692,55 @@ self.IndentLeft() for initialstep in self.InitialSteps: self.ComputeSFCStep(initialstep) + else: + orderedInstances = [] + otherInstances = {"outVariables" : [], "block" : [], "connector" : [], "coil" : []} + for instance in body.getcontentInstances(): + if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable, plcopen.fbdObjects_block)): + executionOrderId = instance.getexecutionOrderId() + if executionOrderId > 0: + orderedInstances.append((executionOrderId, instance)) + elif isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)): + otherInstances["outVariables"].append(instance) + elif isinstance(instance, plcopen.fbdObjects_block): + otherInstances["block"].append(instance) + elif isinstance(instance, plcopen.commonObjects_connector): + otherInstances["connector"].append(instance) + elif isinstance(instance, plcopen.ldObjects_coil): + otherInstances["coil"].append(instance) + orderedInstances.sort() + instances = [instance for (executionOrderId, instance) in orderedInstances] + instances.extend(otherInstances["connector"] + otherInstances["outVariables"] + otherInstances["coil"] + otherInstances["block"]) + for instance in instances: + if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)): + connections = instance.connectionPointIn.getconnections() + if connections is not None: + expression = self.ComputeExpression(body, connections) + self.Program += [(self.CurrentIndent, ()), + (instance.getexpression(), (self.TagName, "io_variable", instance.getlocalId(), "expression")), + (" := ", ())] + self.Program += expression + self.Program += [(";\n", ())] + elif isinstance(instance, plcopen.fbdObjects_block): + block_type = instance.gettypeName() + self.ParentGenerator.GeneratePouProgram(block_type) + block_infos = self.GetBlockType(block_type) + block_infos["generate"](self, instance, body, None) + elif isinstance(instance, plcopen.commonObjects_connector): + connector = instance.getname() + if self.ComputedConnectors.get(connector, None): + continue + self.ComputedConnectors[connector] = self.ComputeExpression(body, instance.connectionPointIn.getconnections()) + elif isinstance(instance, plcopen.ldObjects_coil): + connections = instance.connectionPointIn.getconnections() + if connections is not None: + expression = self.ComputeExpression(body, connections) + coil_info = (self.TagName, "coil", instance.getlocalId()) + variable = self.ExtractModifier(instance, [(instance.getvariable(), coil_info + ("reference",))], coil_info) + self.Program += [(self.CurrentIndent, ())] + variable + self.Program += [(" := ", ())] + expression + [(";\n", ())] - def ComputeFBDExpression(self, body, link, order = False): - localid = link.getrefLocalId() - instance = body.getcontentInstance(localid) - if isinstance(instance, (plcopen.fbdObjects_inVariable, plcopen.fbdObjects_inOutVariable)): - return [(instance.getexpression(), (self.TagName, "io_variable", localid, "expression"))] - elif isinstance(instance, plcopen.fbdObjects_block): - block_type = instance.gettypeName() - self.ParentGenerator.GeneratePouProgram(block_type) - block_infos = self.GetBlockType(block_type) - return block_infos["generate"](self, instance, body, link, order) - elif isinstance(instance, plcopen.commonObjects_continuation): - name = instance.getname() - computed_value = self.ComputedConnectors.get(name, None) - if computed_value != None: - return computed_value - for tmp_instance in body.getcontentInstances(): - if isinstance(tmp_instance, plcopen.commonObjects_connector): - if tmp_instance.getname() == name: - connections = tmp_instance.connectionPointIn.getconnections() - if connections and len(connections) == 1: - expression = self.ComputeFBDExpression(body, connections[0], order) - self.ComputedConnectors[name] = expression - return expression - raise PLCGenException, "No connector found corresponding to \"%s\" continuation in \"%s\" POU"%(name, self.Name) - - def FactorizeLDPaths(self, paths): + def FactorizePaths(self, paths): same_paths = {} uncomputed_index = range(len(paths)) factorized_paths = [] @@ -788,24 +763,40 @@ factorized_paths.sort() return factorized_paths - def GenerateLDPaths(self, connections, body): + def GeneratePaths(self, connections, body, order = False): paths = [] for connection in connections: localId = connection.getrefLocalId() next = body.getcontentInstance(localId) if isinstance(next, plcopen.ldObjects_leftPowerRail): paths.append(None) + elif isinstance(next, (plcopen.fbdObjects_inVariable, plcopen.fbdObjects_inOutVariable)): + paths.append(str([(next.getexpression(), (self.TagName, "io_variable", localId, "expression"))])) elif isinstance(next, plcopen.fbdObjects_block): block_type = next.gettypeName() self.ParentGenerator.GeneratePouProgram(block_type) block_infos = self.GetBlockType(block_type) - paths.append(str(block_infos["generate"](self, next, body, connection))) + paths.append(str(block_infos["generate"](self, next, body, connection, order))) + elif isinstance(next, plcopen.commonObjects_continuation): + name = next.getname() + computed_value = self.ComputedConnectors.get(name, None) + if computed_value != None: + paths.append(computed_value) + for tmp_instance in body.getcontentInstances(): + if isinstance(tmp_instance, plcopen.commonObjects_connector): + if tmp_instance.getname() == name: + connections = tmp_instance.connectionPointIn.getconnections() + if connections is not None: + expression = str(self.ComputeExpression(body, connections, order)) + self.ComputedConnectors[name] = expression + paths.append(expression) + raise PLCGenException, "No connector found corresponding to \"%s\" continuation in \"%s\" POU"%(name, self.Name) else: contact_info = (self.TagName, "contact", next.getlocalId()) variable = str(self.ExtractModifier(next, [(next.getvariable(), contact_info + ("reference",))], contact_info)) - result = self.GenerateLDPaths(next.connectionPointIn.getconnections(), body) + result = self.GeneratePaths(next.connectionPointIn.getconnections(), body, order) if len(result) > 1: - factorized_paths = self.FactorizeLDPaths(result) + factorized_paths = self.FactorizePaths(result) if len(factorized_paths) > 1: paths.append([variable, tuple(factorized_paths)]) else: @@ -818,33 +809,33 @@ paths.append(variable) return paths - def ComputeLDPaths(self, paths, first = False): + def ComputePaths(self, paths, first = False): if type(paths) == TupleType: if None in paths: return [("TRUE", ())] else: - vars = [self.ComputeLDPaths(path) for path in paths] + vars = [self.ComputePaths(path) for path in paths] if first: return JoinList([(" OR ", ())], vars) else: return [("(", ())] + JoinList([(" OR ", ())], vars) + [(")", ())] elif type(paths) == ListType: - vars = [self.ComputeLDPaths(path) for path in paths] + vars = [self.ComputePaths(path) for path in paths] return JoinList([(" AND ", ())], vars) else: return eval(paths) - def ComputeLDExpression(self, body, connections): - paths = self.GenerateLDPaths(connections, body) + def ComputeExpression(self, body, connections, order = False): + paths = self.GeneratePaths(connections, body, order) if len(paths) > 1: - factorized_paths = self.FactorizeLDPaths(paths) + factorized_paths = self.FactorizePaths(paths) if len(factorized_paths) > 1: paths = tuple(factorized_paths) else: paths = factorized_paths[0] else: paths = paths[0] - return self.ComputeLDPaths(paths, True) + return self.ComputePaths(paths, True) def ExtractModifier(self, variable, expression, var_info): if variable.getnegated(): @@ -1025,36 +1016,25 @@ elif transitionType == "ST": transition_infos["content"] = [("\n", ()), (ReIndentText(transitionBody.gettext(), len(self.CurrentIndent)), (self.TagName, "body", len(self.CurrentIndent)))] - elif transitionType == "FBD": + else: for instance in transitionBody.getcontentInstances(): - if isinstance(instance, plcopen.fbdObjects_outVariable): + if isinstance(instance, plcopen.fbdObjects_outVariable) and instance.getexpression() == transitionValues["value"]\ + or isinstance(instance, plcopen.ldObjects_coil) and instance.getvariable() == transitionValues["value"]: connections = instance.connectionPointIn.getconnections() - if connections and len(connections) == 1: - expression = self.ComputeFBDExpression(transitionBody, connections[0]) + if connections is not None: + expression = self.ComputeExpression(transitionBody, connections) transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())] self.SFCComputedBlocks += self.Program self.Program = [] - elif transitionType == "LD": - for instance in transitionBody.getcontentInstances(): - if isinstance(instance, plcopen.ldObjects_coil): - expression = self.ComputeLDExpression(transitionBody, instance.connectionPointIn.getconnections()) - transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())] - self.SFCComputedBlocks += self.Program - self.Program = [] self.TagName = previous_tagname elif transitionValues["type"] == "connection": body = pou.getbody() connections = transition.getconnections() - network_type = self.GetNetworkType(connections, body) - if network_type == None: - raise PLCGenException, "Type of network connected to transition impossible to define in \"%s\" POU"%self.Name - if len(connections) > 1 or network_type == "LD": - expression = self.ComputeLDExpression(body, connections) - else: - expression = self.ComputeFBDExpression(body, connections[0]) - transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())] - self.SFCComputedBlocks += self.Program - self.Program = [] + if connections is not None: + expression = self.ComputeExpression(body, connections) + transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())] + self.SFCComputedBlocks += self.Program + self.Program = [] for step in steps: self.GenerateSFCStep(step, pou) step_name = step.getname()