ML-for-AGV-Dispatching:Center.py逐段解读

发布时间 2023-07-07 18:16:25作者: diejobdeath
class Center(object):
    def __init__(self, env, x, y, routRule, AGV_num, WS_num, AGV_disRuleV, AGV_disRuleW, Ledispatch = "None", Task = ["None", "None"]):
        self.Warmup = 2000
        self.Period = 2000
        
        self.env = env
        self.Time = 0
        self.AGVs = []
        self.x = x
        self.y = y
        self.AGV_num = AGV_num
        self.routRule = routRule
        self.Parameter = [0.6, 0.3, 0.1, 3, 7]
        self.Task = Task
        
        self.FTmatrix = [[0, 15, 5, 8, 15, 18, 21, 20, 17, 14, 10, 1],
                         [15, 0, 10, 9, 8, 5, 6, 5, 8, 11, 5, 16],
                         [5, 10, 0, 3, 10, 13, 16, 15, 14, 17, 9, 6],
                         [8, 9, 3, 0, 7, 10, 13, 14, 13, 16, 10, 9],
                         [15, 8, 10, 7, 0, 3, 6, 13, 16, 19, 13, 16],
                         [18, 5, 13, 10, 3, 0, 3, 10, 13, 16, 11, 19],
                         [21, 6, 16, 13, 6, 3, 0, 7, 10, 13, 11, 22],
                         [20, 5, 15, 14, 13, 10, 7, 0, 3, 6, 10, 21],
                         [17, 8, 14, 13, 16, 13, 10, 3, 0, 3, 7, 18],
                         [14, 11, 17, 16, 19, 16, 13, 6, 3, 0, 6, 15],
                         [10, 5, 9, 10, 13, 11, 11, 10, 7, 6, 0, 11],
                         [1, 16, 6, 9, 16, 19, 22, 21, 18, 15, 11, 0]]
        
        PD = [[9, 8], [5, 2], [8, 2], [13, 4], [13, 7], [13, 10], [3, 13], [6, 13], [9, 13], [4, 8]]
        self.BLOCK = []
        for i in range(len(PD)):
            block = PD[i]
            if i == 0 or i == 1 or i == 2 or i == 9:
                block[1] -= 1
                self.BLOCK.append(block)
                self.BLOCK.append([block[0] - 1, block[1] - 1])
                self.BLOCK.append([block[0] - 1, block[1]])
                self.BLOCK.append([block[0], block[1] - 1])
                self.BLOCK.append([block[0] + 1, block[1] - 1])
                self.BLOCK.append([block[0] + 1, block[1]])
            elif i == 6 or i == 7 or i == 8:
                block[1] += 2
                self.BLOCK.append(block)
                self.BLOCK.append([block[0] - 1, block[1] - 1])
                self.BLOCK.append([block[0] - 1, block[1]])
                self.BLOCK.append([block[0], block[1] - 1])
                self.BLOCK.append([block[0] + 1, block[1] - 1])
                self.BLOCK.append([block[0] + 1, block[1]])
            else:
                block[0] += 1
                self.BLOCK.append(block)
                self.BLOCK.append([block[0], block[1] - 1])
                self.BLOCK.append([block[0], block[1] + 1])
                self.BLOCK.append([block[0] + 1, block[1] - 1])
                self.BLOCK.append([block[0] + 1, block[1]])
                self.BLOCK.append([block[0] + 1, block[1] + 1])
                
        
        
        self.V1 = 0 #The Vehicle found conflict
        self.V2 = 0 #The Vehicle V1 encounter
        
        
        self.mesh = self.create_path(self.env, x, y, 1, self.BLOCK)
        self.speed = 15
        #self.env.process(self.Conflict_Controll())
        self.env.process(self.TimeCount())
        self.env.process(self.Job_arrive())
        
        ###
        self.Hight = self.y-1
        self.Width = self.x-1
        self.unit = 40
        self.Origin = [3, 2]
        self.split = 5
        self.BuildFloor()
        
        self.jobs = []
        self.job_num = 0
        self.Rtravel = 0
        self.IV = []
        self.IV_num = 0
        self.stations = []
        self.WS_num = WS_num
        
        
        self.Tardiness = []
        self.MeanTardiness = 0
        self.FlowTime = []
        self.sysJob = []
        self.Makespan = 0
        self.Throughput = 0
        
        self.Create_Stations()
        self.Create_AGVs()
        #self.Create_Jobs()
        
        self.status = Le.Status(self)
        self.AGV_disRuleV = 0
        self.AGV_disRuleW = 0
        
        if AGV_disRuleV >= 6 or self.Task[0] == "Collect":
            self.set_LE(Ledispatch[0], "None", "V")
        self.tempV = AGV_disRuleV
            
        if AGV_disRuleW >= 3 or self.Task[1] == "Collect":
            self.set_LE("None", Ledispatch[1], "W")
        self.tempW = AGV_disRuleW
            
        
        self.Cstation = Charging(self.env, self, x=0, y=10)
        
    def set_LE(self, LEV, LEW, Type):
        if Type == "V":
            self.LEV = LEV
        elif Type == "W":
            self.LEW = LEW
        
        
                        
    def create_path(self, env, x, y, Capacity, block):
        mesh = []
        for i in range(y):
            temp = []
            for j in range(x):
                if [i, j] in block:
                    a = simpy.Resource(env, 1)
                    temp.append(a)
                elif [i, j] in [[9, 8], [5, 2], [8, 2], [13, 4], [13, 7], [13, 10], [3, 13], [6, 13], [9, 13], [4, 8], [0, 1], [0, 2]]:
                    a = simpy.Resource(env, 1)
                    temp.append(a)
                else:
                    temp.append(simpy.Resource(env, Capacity))
            mesh.append(temp)
        return mesh
        

    def Job_arrive(self):
        
        while True:
            inter_arrival = np.random.exponential(34)
                
            yield self.env.timeout(inter_arrival)
            t = np.random.choice(range(10))
            Job(self.env, self, t+1)
            '''
        while True:
            inter_arrival = np.random.exponential(105)
                
            yield self.env.timeout(inter_arrival)
            t = np.random.choice(range(10))
            Job(self.env, self, t+1)
            
        while True:
            inter_arrival = np.random.exponential(36)
                
            yield self.env.timeout(inter_arrival)
            t = np.random.choice(range(10))
            a = Job(self.env, self, t+1)
            a.create2(t+1)
            
        while True:
            inter_arrival = np.random.exponential(54)
                
            yield self.env.timeout(inter_arrival)
            t = np.random.choice(range(10))
            a = Job(self.env, self, t+1)
            a.create2(t+1)
            '''
    
    def TimeCount(self):
        yield self.env.timeout(0)
        self.Time = 0
        while True > 0:
            yield self.env.timeout(1)
            self.Time += 1
            
            self.canvas.delete(self.time)
                
            self.TIME = self.canvas.create_text(self.unit\
                                            , 0.5*self.unit, text = "Time:"\
                                            , font = ("arial", 20)\
                                            , fill = "Blue")
            self.time = self.canvas.create_text(2.5*self.unit\
                                            , 0.5*self.unit, text = str(round(self.Time))\
                                            , font = ("arial", 20)\
                                            , fill = "Blue")
            
            for i in range(self.split):
                    
                yield self.env.timeout(1/self.split)
                self.Time += 1/self.split
                if self.speed < 50:
                    time.sleep(1/(self.split*self.speed))
                    
                    
                    
            if round(self.Time) == self.Warmup:
                if hasattr(self, "LEV") and self.Task[0] != "Collect":
                    if self.tempV == 6:
                        s = self.status.Get("v")
                    else:
                        s = self.status.Get("V")
                    self.status.currentstate[0] = s
                    a = self.LEV.Choose_act(s)
                    self.status.currentact[0] = a
                    self.AGV_disRuleV = a
                elif self.Task[0] == "Collect":
                    self.status.currentstate[0] = self.status.Get("V")
                    self.AGV_disRuleV = self.tempV
                else:
                    self.AGV_disRuleV = self.tempV
                if hasattr(self, "LEW") and self.Task[1] != "Collect":
                    if self.tempW == 3:
                        s = self.status.Get("w")
                    else:
                        s = self.status.Get("W")
                    self.status.currentstate[1] = s
                    a = self.LEW.Choose_act(s)
                    self.status.currentact[1] = a
                    self.AGV_disRuleW = a
                elif self.Task[1] == "Collect":
                    self.status.currentstate[1] = self.status.Get("W")
                    self.AGV_disRuleW = self.tempW
                else:
                    self.AGV_disRuleW = self.tempW
                    
                self.Tardiness = []
                self.status.tardiness = []
            

            if round(self.Time - self.Warmup) % self.Period == 0 and round(self.Time) > self.Warmup:
                #Vehicle Initiated LE
                
                if hasattr(self, "LEV") or self.Task[0] == "Collect":
                    s = self.status.currentstate[0]
                    s_ = self.status.Get("V")
                    r = -self.status.meantardiness
                    if self.Task[0] == "Collect":
                        self.LEV.Memorize(s, r)
                    elif self.tempV == 8:
                        self.AGV_disRuleV = self.LEV.Choose_act(s_)
                    else:
                        self.status.currentstate[0] = s_
                        a = self.status.currentact[0]
                        self.AGV_disRuleV = self.LEV.Choose_act(s_)
                        if self.tempV == 6:
                            s_ = self.status.Get("v")
                            self.LEV.Learning(s, a, s_, r)
                        else:
                            self.LEV.store_transition(s, a, s_, r)
                        self.status.currentact[0] = self.AGV_disRuleV
                
                if hasattr(self, "LEW") or self.Task[1] == "Collect":
                    s = self.status.currentstate[1]
                    s_ = self.status.Get("W")
                    r = -self.status.meantardiness
                    if self.Task[1] == "Collect":
                        self.LEW.Memorize(s, r)
                    elif self.tempW == 5:
                        self.AGV_disRuleW = self.LEW.Choose_act(s_)
                    else:
                        self.status.currentstate[1] = s_
                        a = self.status.currentact[1]
                        self.AGV_disRuleW = self.LEW.Choose_act(s_)
                        if self.tempW == 3:
                            s_ = self.status.Get("w")
                            self.LEW.Learning(s, a, s_, r)
                        else:
                            self.LEW.store_transition(s, a, s_, r)
                        self.status.currentact[1] = self.AGV_disRuleW
                    
                    self.status.tardiness = []
                    self.status.throughput = 0
                    self.status.meantardiness = 0
                    
            for i in self.AGVs:
                i.Electricity -= 1/7200
            
            if round(self.Time - self.Warmup) % 500 == 0:
                tard = copy.deepcopy(self.Tardiness)
                tard1 = copy.deepcopy(self.status.tardiness)
                for i in self.sysJob:
                    tard.append(max(0, self.env.now - i.DueDate))
                    tard1.append(max(0, self.env.now - i.DueDate))
                self.MeanTardiness = np.mean(tard)
                self.status.meantardiness = np.mean(tard1)
                
                
                
    def Create_Stations(self):
        for i in range(self.WS_num):
            Station(self.env, self, i)
            
    def Create_AGVs(self):
        for i in range(self.AGV_num):
            Vehicle(self.env, self, self.mesh, i+1, x = 0, y = 10)
            
    def Create_Jobs(self):
        for i in range(10):
            Job(self.env, self, i+1)
            
    def BuildFloor(self):
        
        self.window = tk.Tk()
        
        self.window.title("Flexible Manufacturing System")
        self.window.geometry("{1}x{1}".format((self.Hight+4)*self.unit
                      , (self.Width+5)*self.unit))
        self.canvas = tk.Canvas(bg = "white", height = (self.Hight+5)\
                *self.unit, width = (self.Width+5)*self.unit)

        #Grid Layout
        for c in range(0, (self.Width*self.unit+1), self.unit):
            x0, y0, x1, y1 = self.Origin[0]*self.unit+c, self.Origin[1]*self.unit\
                    , self.Origin[0]*self.unit+c, (self.Hight+self.Origin[1])\
                    *self.unit
            self.canvas.create_line(x0, y0, x1, y1)

        for r in range(0, (self.Hight*self.unit+1), self.unit):
            x0, y0, x1, y1 = self\
                    .Origin[0]*self.unit, self.Origin[1]*self.unit+r\
                    , (self.Width+self.Origin[0])*self.unit\
                    , self.Origin[1]*self.unit+r
            self.canvas.create_line(x0, y0, x1, y1)

        #Loading Point
        L = [[0, 2]]
        for i in range(len(L)):
            p1 = [(self.Origin[0]+L[i][0])*self.unit-5, (self.Origin[1]+self.Hight-L[i][1])\
                  *self.unit-5]
            p2 = [(self.Origin[0]+L[i][0])*self.unit+5, (self.Origin[1]+self.Hight-L[i][1])\
                  *self.unit+5]
            self.canvas.create_oval(p1[0], p1[1], p2[0], p2[1], fill = "blue")
        #Unloading Point
        U = [[0, 1]]
        for i in range(len(U)):
            p1 = [(self.Origin[0]+U[i][0])*self.unit-5, (self.Origin[1]+self.Hight-U[i][1])\
                  *self.unit-5]
            p2 = [(self.Origin[0]+U[i][0])*self.unit+5, (self.Origin[1]+self.Hight-U[i][1])\
                  *self.unit+5]
            self.canvas.create_oval(p1[0], p1[1], p2[0], p2[1], fill = "green")
        #P/D Point
        PD = [[9, 8], [5, 2], [8, 2], [13, 4], [13, 7], [13, 10], [3, 13], [6, 13], [9, 13], [4, 8]]
        for i in range(len(PD)):
            p1 = [(self.Origin[0]+PD[i][0])*self.unit-5, (self.Origin[1]\
                  +self.Hight-PD[i][1])*self.unit-5]
            p2 = [(self.Origin[0]+PD[i][0])*self.unit+5, (self.Origin[1]\
                  +self.Hight-PD[i][1])*self.unit+5]
            self.canvas.create_oval(p1[0], p1[1], p2[0], p2[1], fill = "black")
            

        #AS/RS
        p = [1.5*self.unit, (self.Origin[1]+self.Hight*3/4+1)*self.unit]
        p1 = [2.5*self.unit, (self.Origin[1]+self.Hight*3/4+4)*self.unit]
        p2 = [0.5*self.unit, (self.Origin[1]+self.Hight*3/4-2)*self.unit]
        self.canvas.create_rectangle(p1[0], p1[1], p2[0], p2[1]\
                                     , fill = "yellow")
        self.canvas.create_text(p[0], p[1], text = "AS/RS"
                                , font = ("arial", 12), fill = "black")

        #Workstations
        for i in range(len(PD)):
            if i == 0 or i == 1 or i == 2 or i == 9:
                PD[i][1] -= 1.5
            elif i == 3 or i == 4 or i == 5:
                PD[i][0] += 1.5
            else:
                PD[i][1] += 1.5
        for i in range(len(PD)):
            p = [(self.Origin[0]+PD[i][0])*self.unit, (self.Origin[1]\
                 +self.Hight-PD[i][1])*self.unit]
            if i == 3 or i == 4 or i == 5:
                p1 = [(self.Origin[0]+PD[i][0]-1)*self.unit, (self.Origin[1]\
                      +self.Hight-PD[i][1]-1.5)\
                      *self.unit]
                p2 = [(self.Origin[0]+PD[i][0]+1)*self.unit, (self.Origin[1]\
                      +self.Hight-PD[i][1]+1.5)\
                      *self.unit]
            else:
                p1 = [(self.Origin[0]+PD[i][0]-1.5)*self.unit, (self.Origin[1]\
                      +self.Hight-PD[i][1]-1)\
                      *self.unit]
                p2 = [(self.Origin[0]+PD[i][0]+1.5)*self.unit, (self.Origin[1]\
                      +self.Hight-PD[i][1]+1)\
                      *self.unit]
            self.canvas.create_rectangle(p1[0], p1[1], p2[0], p2[1]\
                                         , fill = "orange")
            self.canvas.create_text(p[0], p[1], text = "W"+str(i+1)\
                                    , font = ("arial", 15), fill = "black")
            
        self.time = self.canvas.create_text(2.5*self.unit\
                                            , 0.5*self.unit, text = ""\
                                            , font = ("arial", 20)\
                                            , fill = "Blue")

        
        self.canvas.pack()