Problem with multi-connection on block in LD fixed
authorlbessard
Fri, 05 Sep 2008 18:12:23 +0200
changeset 248 f7df265edd54
parent 247 4a47ccafbef7
child 249 d8425712acef
Problem with multi-connection on block in LD fixed
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()