712 if connections and len(connections) == 1: |
712 if connections and len(connections) == 1: |
713 self.ComputedConnectors[connector] = self.ComputeFBDExpression(body, connections[0]) |
713 self.ComputedConnectors[connector] = self.ComputeFBDExpression(body, connections[0]) |
714 elif body_type == "LD": |
714 elif body_type == "LD": |
715 for instance in body.getcontentInstances(): |
715 for instance in body.getcontentInstances(): |
716 if isinstance(instance, plcopen.ldObjects_coil): |
716 if isinstance(instance, plcopen.ldObjects_coil): |
717 paths = self.GenerateLDPaths(instance.connectionPointIn.getconnections(), body) |
717 expression = self.ComputeLDExpression(body, instance.connectionPointIn.getconnections()) |
718 if len(paths) > 0: |
|
719 paths = tuple(paths) |
|
720 else: |
|
721 paths = paths[0] |
|
722 coil_info = (self.TagName, "coil", instance.getlocalId()) |
718 coil_info = (self.TagName, "coil", instance.getlocalId()) |
723 variable = self.ExtractModifier(instance, [(instance.getvariable(), coil_info + ("reference",))], coil_info) |
719 variable = self.ExtractModifier(instance, [(instance.getvariable(), coil_info + ("reference",))], coil_info) |
724 expression = self.ComputeLDExpression(paths, True) |
|
725 self.Program += [(self.CurrentIndent, ())] + variable |
720 self.Program += [(self.CurrentIndent, ())] + variable |
726 self.Program += [(" := ", ())] + expression + [(";\n", ())] |
721 self.Program += [(" := ", ())] + expression + [(";\n", ())] |
727 elif body_type == "SFC": |
722 elif body_type == "SFC": |
728 self.IndentRight() |
723 self.IndentRight() |
729 for instance in body.getcontentInstances(): |
724 for instance in body.getcontentInstances(): |
768 expression = self.ComputeFBDExpression(body, connections[0], order) |
763 expression = self.ComputeFBDExpression(body, connections[0], order) |
769 self.ComputedConnectors[name] = expression |
764 self.ComputedConnectors[name] = expression |
770 return expression |
765 return expression |
771 raise PLCGenException, "No connector found corresponding to \"%s\" continuation in \"%s\" POU"%(name, self.Name) |
766 raise PLCGenException, "No connector found corresponding to \"%s\" continuation in \"%s\" POU"%(name, self.Name) |
772 |
767 |
|
768 def FactorizeLDPaths(self, paths): |
|
769 same_paths = {} |
|
770 uncomputed_index = range(len(paths)) |
|
771 factorized_paths = [] |
|
772 for num, path in enumerate(paths): |
|
773 if type(path) == ListType: |
|
774 for i in xrange(1, len(path)): |
|
775 str_path = str(path[i:]) |
|
776 same_paths.setdefault(str_path, []) |
|
777 same_paths[str_path].append((path[:i], num)) |
|
778 else: |
|
779 factorized_paths.append(path) |
|
780 uncomputed_index.remove(num) |
|
781 for same_path, elements in same_paths.items(): |
|
782 if len(elements) > 1: |
|
783 factorized_paths.append([tuple([path for path, num in elements])] + eval(same_path)) |
|
784 for path, num in elements: |
|
785 uncomputed_index.remove(num) |
|
786 for num in uncomputed_index: |
|
787 factorized_paths.append(paths[num]) |
|
788 return factorized_paths |
|
789 |
773 def GenerateLDPaths(self, connections, body): |
790 def GenerateLDPaths(self, connections, body): |
774 paths = [] |
791 paths = [] |
775 for connection in connections: |
792 for connection in connections: |
776 localId = connection.getrefLocalId() |
793 localId = connection.getrefLocalId() |
777 next = body.getcontentInstance(localId) |
794 next = body.getcontentInstance(localId) |
785 else: |
802 else: |
786 contact_info = (self.TagName, "contact", next.getlocalId()) |
803 contact_info = (self.TagName, "contact", next.getlocalId()) |
787 variable = str(self.ExtractModifier(next, [(next.getvariable(), contact_info + ("reference",))], contact_info)) |
804 variable = str(self.ExtractModifier(next, [(next.getvariable(), contact_info + ("reference",))], contact_info)) |
788 result = self.GenerateLDPaths(next.connectionPointIn.getconnections(), body) |
805 result = self.GenerateLDPaths(next.connectionPointIn.getconnections(), body) |
789 if len(result) > 1: |
806 if len(result) > 1: |
790 paths.append([variable, tuple(result)]) |
807 factorized_paths = self.FactorizeLDPaths(result) |
|
808 if len(factorized_paths) > 1: |
|
809 paths.append([variable, tuple(factorized_paths)]) |
|
810 else: |
|
811 paths.append([variable] + factorized_paths) |
791 elif type(result[0]) == ListType: |
812 elif type(result[0]) == ListType: |
792 paths.append([variable] + result[0]) |
813 paths.append([variable] + result[0]) |
793 elif result[0]: |
814 elif result[0] is not None: |
794 paths.append([variable, result[0]]) |
815 paths.append([variable, result[0]]) |
795 else: |
816 else: |
796 paths.append(variable) |
817 paths.append(variable) |
797 return paths |
818 return paths |
798 |
819 |
799 def ComputeLDExpression(self, paths, first = False): |
820 def ComputeLDPaths(self, paths, first = False): |
800 if type(paths) == TupleType: |
821 if type(paths) == TupleType: |
801 if None in paths: |
822 if None in paths: |
802 return [("TRUE", ())] |
823 return [("TRUE", ())] |
803 else: |
824 else: |
804 vars = [self.ComputeLDExpression(path) for path in paths] |
825 vars = [self.ComputeLDPaths(path) for path in paths] |
805 if first: |
826 if first: |
806 return JoinList([(" OR ", ())], vars) |
827 return JoinList([(" OR ", ())], vars) |
807 else: |
828 else: |
808 return [("(", ())] + JoinList([(" OR ", ())], vars) + [(")", ())] |
829 return [("(", ())] + JoinList([(" OR ", ())], vars) + [(")", ())] |
809 elif type(paths) == ListType: |
830 elif type(paths) == ListType: |
810 vars = [self.ComputeLDExpression(path) for path in paths] |
831 vars = [self.ComputeLDPaths(path) for path in paths] |
811 return JoinList([(" AND ", ())], vars) |
832 return JoinList([(" AND ", ())], vars) |
812 else: |
833 else: |
813 return eval(paths) |
834 return eval(paths) |
|
835 |
|
836 def ComputeLDExpression(self, body, connections): |
|
837 paths = self.GenerateLDPaths(connections, body) |
|
838 if len(paths) > 1: |
|
839 factorized_paths = self.FactorizeLDPaths(paths) |
|
840 if len(factorized_paths) > 1: |
|
841 paths = tuple(factorized_paths) |
|
842 else: |
|
843 paths = factorized_paths[0] |
|
844 else: |
|
845 paths = paths[0] |
|
846 return self.ComputeLDPaths(paths, True) |
814 |
847 |
815 def ExtractModifier(self, variable, expression, var_info): |
848 def ExtractModifier(self, variable, expression, var_info): |
816 if variable.getnegated(): |
849 if variable.getnegated(): |
817 return [("NOT(", var_info + ("negated",))] + expression + [(")", ())] |
850 return [("NOT(", var_info + ("negated",))] + expression + [(")", ())] |
818 else: |
851 else: |
1001 self.SFCComputedBlocks += self.Program |
1034 self.SFCComputedBlocks += self.Program |
1002 self.Program = [] |
1035 self.Program = [] |
1003 elif transitionType == "LD": |
1036 elif transitionType == "LD": |
1004 for instance in transitionBody.getcontentInstances(): |
1037 for instance in transitionBody.getcontentInstances(): |
1005 if isinstance(instance, plcopen.ldObjects_coil): |
1038 if isinstance(instance, plcopen.ldObjects_coil): |
1006 paths = self.GenerateLDPaths(instance.connectionPointIn.getconnections(), transitionBody) |
1039 expression = self.ComputeLDExpression(transitionBody, instance.connectionPointIn.getconnections()) |
1007 expression = self.ComputeLDExpression(paths, True) |
|
1008 transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())] |
1040 transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())] |
1009 self.SFCComputedBlocks += self.Program |
1041 self.SFCComputedBlocks += self.Program |
1010 self.Program = [] |
1042 self.Program = [] |
1011 self.TagName = previous_tagname |
1043 self.TagName = previous_tagname |
1012 elif transitionValues["type"] == "connection": |
1044 elif transitionValues["type"] == "connection": |
1014 connections = transition.getconnections() |
1046 connections = transition.getconnections() |
1015 network_type = self.GetNetworkType(connections, body) |
1047 network_type = self.GetNetworkType(connections, body) |
1016 if network_type == None: |
1048 if network_type == None: |
1017 raise PLCGenException, "Type of network connected to transition impossible to define in \"%s\" POU"%self.Name |
1049 raise PLCGenException, "Type of network connected to transition impossible to define in \"%s\" POU"%self.Name |
1018 if len(connections) > 1 or network_type == "LD": |
1050 if len(connections) > 1 or network_type == "LD": |
1019 paths = self.GenerateLDPaths(connections, body) |
1051 expression = self.ComputeLDExpression(body, connections) |
1020 expression = self.ComputeLDExpression(paths, True) |
|
1021 else: |
1052 else: |
1022 expression = self.ComputeFBDExpression(body, connections[0]) |
1053 expression = self.ComputeFBDExpression(body, connections[0]) |
1023 transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())] |
1054 transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())] |
1024 self.SFCComputedBlocks += self.Program |
1055 self.SFCComputedBlocks += self.Program |
1025 self.Program = [] |
1056 self.Program = [] |