def showDomain(self, a=0): s = self.state if self.domain_fig is None: self.domain_fig = plt.figure( 1, (UAVLocation.SIZE * self.dist_between_locations + 1, self.NUM_UAV + 1)) plt.show() plt.clf() # Draw the environment # Allocate horizontal 'lanes' for UAVs to traverse # Formerly, we checked if this was the first time plotting; wedge shapes cannot be removed from # matplotlib environment, nor can their properties be changed, without clearing the figure # Thus, we must redraw the figure on each timestep # if self.location_rect_vis is None: # Figure with x width corresponding to number of location states, UAVLocation.SIZE # and rows (lanes) set aside in y for each UAV (NUM_UAV total lanes). # Add buffer of 1 self.subplot_axes = self.domain_fig.add_axes([0, 0, 1, 1], frameon=False, aspect=1.) crashLocationX = 2 * \ (self.dist_between_locations) * (UAVLocation.SIZE - 1) self.subplot_axes.set_xlim(0, 1 + crashLocationX + self.RECT_GAP) self.subplot_axes.set_ylim(0, 1 + self.NUM_UAV) self.subplot_axes.xaxis.set_visible(False) self.subplot_axes.yaxis.set_visible(False) # Assign coordinates of each possible uav location on figure self.location_coord = [ 0.5 + (self.LOCATION_WIDTH / 2) + (self.dist_between_locations) * i for i in range(UAVLocation.SIZE - 1) ] self.location_coord.append(crashLocationX + self.LOCATION_WIDTH / 2) # Create rectangular patches at each of those locations self.location_rect_vis = [ mpatches.Rectangle([0.5 + (self.dist_between_locations) * i, 0], self.LOCATION_WIDTH, self.NUM_UAV * 2, fc='w') for i in range(UAVLocation.SIZE - 1) ] self.location_rect_vis.append( mpatches.Rectangle([crashLocationX, 0], self.LOCATION_WIDTH, self.NUM_UAV * 2, fc='w')) [ self.subplot_axes.add_patch(self.location_rect_vis[i]) for i in range(4) ] self.comms_line = [ lines.Line2D([ 0.5 + self.LOCATION_WIDTH + (self.dist_between_locations) * i, 0.5 + self.LOCATION_WIDTH + (self.dist_between_locations) * i + self.RECT_GAP ], [self.NUM_UAV * 0.5 + 0.5, self.NUM_UAV * 0.5 + 0.5], linewidth=3, color='black', visible=False) for i in range(UAVLocation.SIZE - 2) ] self.comms_line.append( lines.Line2D([ 0.5 + self.LOCATION_WIDTH + (self.dist_between_locations) * 2, crashLocationX ], [self.NUM_UAV * 0.5 + 0.5, self.NUM_UAV * 0.5 + 0.5], linewidth=3, color='black', visible=False)) # Create location text below rectangles locText = ["Base", "Refuel", "Communication", "Surveillance"] self.location_rect_txt = [ plt.text(0.5 + self.dist_between_locations * i + 0.5 * self.LOCATION_WIDTH, -0.3, locText[i], ha='center') for i in range(UAVLocation.SIZE - 1) ] self.location_rect_txt.append( plt.text(crashLocationX + 0.5 * self.LOCATION_WIDTH, -0.3, locText[UAVLocation.SIZE - 1], ha='center')) # Initialize list of circle objects uav_x = self.location_coord[UAVLocation.BASE] # Update the member variables storing all the figure objects self.uav_circ_vis = [ mpatches.Circle((uav_x, 1 + uav_id), self.UAV_RADIUS, fc="w") for uav_id in range(0, self.NUM_UAV) ] self.uav_text_vis = [None for uav_id in range(0, self.NUM_UAV)] # f**k self.uav_sensor_vis = [ mpatches.Wedge((uav_x + self.SENSOR_REL_X, 1 + uav_id), self.SENSOR_LENGTH, -30, 30) for uav_id in range(0, self.NUM_UAV) ] self.uav_actuator_vis = [ mpatches.Wedge((uav_x, 1 + uav_id + self.ACTUATOR_REL_Y), self.ACTUATOR_HEIGHT, 60, 120) for uav_id in range(0, self.NUM_UAV) ] # The following was executed when we used to check if the environment needed re-drawing: see above. # Remove all UAV circle objects from visualization # else: # [self.uav_circ_vis[uav_id].remove() for uav_id in range(0,self.NUM_UAV)] # [self.uav_text_vis[uav_id].remove() for uav_id in range(0,self.NUM_UAV)] # [self.uav_sensor_vis[uav_id].remove() for uav_id in range(0,self.NUM_UAV)] # For each UAV: # Draw a circle, with text inside = amt fuel remaining # Triangle on top of UAV for comms, black = good, red = bad # Triangle in front of UAV for surveillance sStruct = self.state2Struct(s) for uav_id in range(0, self.NUM_UAV): # Assign all the variables corresponding to this UAV for this iteration; # this could alternately be done with a UAV class whose objects keep track # of these variables. Elect to use lists here since ultimately the state # must be a vector anyway. # State index corresponding to the location of this uav uav_location = sStruct.locations[uav_id] uav_fuel = sStruct.fuel[uav_id] uav_sensor = sStruct.sensor[uav_id] uav_actuator = sStruct.actuator[uav_id] # Assign coordinates on figure where UAV should be drawn uav_x = self.location_coord[uav_location] uav_y = 1 + uav_id # Update plot wit this UAV self.uav_circ_vis[uav_id] = mpatches.Circle((uav_x, uav_y), self.UAV_RADIUS, fc="w") self.uav_text_vis[uav_id] = plt.text(uav_x - 0.05, uav_y - 0.05, uav_fuel) if uav_sensor == SensorState.RUNNING: objColor = 'black' else: objColor = 'red' self.uav_sensor_vis[uav_id] = mpatches.Wedge( (uav_x + self.SENSOR_REL_X, uav_y), self.SENSOR_LENGTH, -30, 30, color=objColor) if uav_actuator == ActuatorState.RUNNING: objColor = 'black' else: objColor = 'red' self.uav_actuator_vis[uav_id] = mpatches.Wedge( (uav_x, uav_y + self.ACTUATOR_REL_Y), self.ACTUATOR_HEIGHT, 60, 120, color=objColor) self.subplot_axes.add_patch(self.uav_circ_vis[uav_id]) self.subplot_axes.add_patch(self.uav_sensor_vis[uav_id]) self.subplot_axes.add_patch(self.uav_actuator_vis[uav_id]) numHealthySurveil = np.sum( np.logical_and(sStruct.locations == UAVLocation.SURVEIL, sStruct.sensor)) # We have comms coverage: draw a line between comms states to show this if (any(sStruct.locations == UAVLocation.COMMS)): for i in xrange(len(self.comms_line)): self.comms_line[i].set_visible(True) self.comms_line[i].set_color('black') self.subplot_axes.add_line(self.comms_line[i]) # We also have UAVs in surveillance; color the comms line black if numHealthySurveil > 0: self.location_rect_vis[len(self.location_rect_vis) - 1].set_color('green') plt.draw() sleep(0.5)
def showDomain(self, a=0): s = self.state if self.domain_fig is None: plt.figure("Domain") self.domain_fig = plt.figure( 1, (UAVLocation.SIZE * self.dist_between_locations + 1, self.NUM_UAV + 1)) plt.show() plt.clf() # Draw the environment # Allocate horizontal 'lanes' for UAVs to traverse # Formerly, we checked if this was the first time plotting; wedge shapes cannot be removed from # matplotlib environment, nor can their properties be changed, without clearing the figure # Thus, we must redraw the figure on each timestep # if self.location_rect_vis is None: # Figure with x width corresponding to number of location states, UAVLocation.SIZE # and rows (lanes) set aside in y for each UAV (NUM_UAV total lanes). # Add buffer of 1 self.subplot_axes = self.domain_fig.add_axes( [0, 0, 1, 1], frameon=False, aspect=1.) crashLocationX = 2 * \ (self.dist_between_locations) * (UAVLocation.SIZE - 1) self.subplot_axes.set_xlim(0, 1 + crashLocationX + self.RECT_GAP) self.subplot_axes.set_ylim(0, 1 + self.NUM_UAV) self.subplot_axes.xaxis.set_visible(False) self.subplot_axes.yaxis.set_visible(False) # Assign coordinates of each possible uav location on figure self.location_coord = [0.5 + (old_div(self.LOCATION_WIDTH, 2)) + (self.dist_between_locations) * i for i in range(UAVLocation.SIZE - 1)] self.location_coord.append(crashLocationX + old_div(self.LOCATION_WIDTH, 2)) # Create rectangular patches at each of those locations self.location_rect_vis = [mpatches.Rectangle( [0.5 + (self.dist_between_locations) * i, 0], self.LOCATION_WIDTH, self.NUM_UAV * 2, fc='w') for i in range(UAVLocation.SIZE - 1)] self.location_rect_vis.append( mpatches.Rectangle([crashLocationX, 0], self.LOCATION_WIDTH, self.NUM_UAV * 2, fc='w')) [self.subplot_axes.add_patch(self.location_rect_vis[i]) for i in range(4)] self.comms_line = [lines.Line2D( [0.5 + self.LOCATION_WIDTH + (self.dist_between_locations) * i, 0.5 + self.LOCATION_WIDTH + ( self.dist_between_locations) * i + self.RECT_GAP], [self.NUM_UAV * 0.5 + 0.5, self.NUM_UAV * 0.5 + 0.5], linewidth=3, color='black', visible=False) for i in range(UAVLocation.SIZE - 2)] self.comms_line.append( lines.Line2D( [0.5 + self.LOCATION_WIDTH + (self.dist_between_locations) * 2, crashLocationX], [self.NUM_UAV * 0.5 + 0.5, self.NUM_UAV * 0.5 + 0.5], linewidth=3, color='black', visible=False)) # Create location text below rectangles locText = ["Base", "Refuel", "Communication", "Surveillance"] self.location_rect_txt = [plt.text( 0.5 + self.dist_between_locations * i + 0.5 * self.LOCATION_WIDTH, -0.3, locText[i], ha='center') for i in range(UAVLocation.SIZE - 1)] self.location_rect_txt.append( plt.text(crashLocationX + 0.5 * self.LOCATION_WIDTH, -0.3, locText[UAVLocation.SIZE - 1], ha='center')) # Initialize list of circle objects uav_x = self.location_coord[UAVLocation.BASE] # Update the member variables storing all the figure objects self.uav_circ_vis = [mpatches.Circle( (uav_x, 1 + uav_id), self.UAV_RADIUS, fc="w") for uav_id in range(0, self.NUM_UAV)] self.uav_text_vis = [None for uav_id in range(0, self.NUM_UAV)] # f**k self.uav_sensor_vis = [mpatches.Wedge( (uav_x + self.SENSOR_REL_X, 1 + uav_id), self.SENSOR_LENGTH, -30, 30) for uav_id in range(0, self.NUM_UAV)] self.uav_actuator_vis = [mpatches.Wedge( (uav_x, 1 + uav_id + self.ACTUATOR_REL_Y), self.ACTUATOR_HEIGHT, 60, 120) for uav_id in range(0, self.NUM_UAV)] # The following was executed when we used to check if the environment needed re-drawing: see above. # Remove all UAV circle objects from visualization # else: # [self.uav_circ_vis[uav_id].remove() for uav_id in range(0,self.NUM_UAV)] # [self.uav_text_vis[uav_id].remove() for uav_id in range(0,self.NUM_UAV)] # [self.uav_sensor_vis[uav_id].remove() for uav_id in range(0,self.NUM_UAV)] # For each UAV: # Draw a circle, with text inside = amt fuel remaining # Triangle on top of UAV for comms, black = good, red = bad # Triangle in front of UAV for surveillance sStruct = self.state2Struct(s) for uav_id in range(0, self.NUM_UAV): # Assign all the variables corresponding to this UAV for this iteration; # this could alternately be done with a UAV class whose objects keep track # of these variables. Elect to use lists here since ultimately the state # must be a vector anyway. # State index corresponding to the location of this uav uav_location = sStruct.locations[uav_id] uav_fuel = sStruct.fuel[uav_id] uav_sensor = sStruct.sensor[uav_id] uav_actuator = sStruct.actuator[uav_id] # Assign coordinates on figure where UAV should be drawn uav_x = self.location_coord[uav_location] uav_y = 1 + uav_id # Update plot wit this UAV self.uav_circ_vis[uav_id] = mpatches.Circle( (uav_x, uav_y), self.UAV_RADIUS, fc="w") self.uav_text_vis[uav_id] = plt.text( uav_x - 0.05, uav_y - 0.05, uav_fuel) if uav_sensor == SensorState.RUNNING: objColor = 'black' else: objColor = 'red' self.uav_sensor_vis[uav_id] = mpatches.Wedge( (uav_x + self.SENSOR_REL_X, uav_y), self.SENSOR_LENGTH, -30, 30, color=objColor) if uav_actuator == ActuatorState.RUNNING: objColor = 'black' else: objColor = 'red' self.uav_actuator_vis[uav_id] = mpatches.Wedge( (uav_x, uav_y + self.ACTUATOR_REL_Y), self.ACTUATOR_HEIGHT, 60, 120, color=objColor) self.subplot_axes.add_patch(self.uav_circ_vis[uav_id]) self.subplot_axes.add_patch(self.uav_sensor_vis[uav_id]) self.subplot_axes.add_patch(self.uav_actuator_vis[uav_id]) numHealthySurveil = np.sum( np.logical_and( sStruct.locations == UAVLocation.SURVEIL, sStruct.sensor)) # We have comms coverage: draw a line between comms states to show this if (any(sStruct.locations == UAVLocation.COMMS)): for i in range(len(self.comms_line)): self.comms_line[i].set_visible(True) self.comms_line[i].set_color('black') self.subplot_axes.add_line(self.comms_line[i]) # We also have UAVs in surveillance; color the comms line black if numHealthySurveil > 0: self.location_rect_vis[ len(self.location_rect_vis) - 1].set_color('green') plt.figure("Domain").canvas.draw() plt.figure("Domain").canvas.flush_events() sleep(0.5)
def showDomain(self, a=0): s = self.state plt.figure("Domain") if self.networkGraph is None: # or self.networkPos is None: self.networkGraph = nx.Graph() # enumerate all computer_ids, simulatenously iterating through # neighbors list and compstatus for computer_id, (neighbors, compstatus) in enumerate(zip(self.NEIGHBORS, s)): # Add a node to network for each computer self.networkGraph.add_node(computer_id, node_color="w") for uniqueEdge in self.UNIQUE_EDGES: self.networkGraph.add_edge( uniqueEdge[0], uniqueEdge[1], edge_color="k") # Add an edge between each neighbor self.networkPos = nx.circular_layout(self.networkGraph) nx.draw_networkx_nodes(self.networkGraph, self.networkPos, node_color="w") nx.draw_networkx_edges(self.networkGraph, self.networkPos, edges_color="k") nx.draw_networkx_labels(self.networkGraph, self.networkPos) plt.show() else: plt.clf() blackEdges = [] redEdges = [] greenNodes = [] redNodes = [] for computer_id, (neighbors, compstatus) in enumerate(zip(self.NEIGHBORS, s)): if (compstatus == self.RUNNING): greenNodes.append(computer_id) else: redNodes.append(computer_id) # Iterate through all unique edges for uniqueEdge in self.UNIQUE_EDGES: if (s[uniqueEdge[0]] == self.RUNNING and s[uniqueEdge[1]] == self.RUNNING): # Then both computers are working blackEdges.append(uniqueEdge) else: # If either computer is BROKEN, make the edge red redEdges.append(uniqueEdge) # "if redNodes", etc. - only draw things in the network if these lists aren't empty / null if redNodes: nx.draw_networkx_nodes(self.networkGraph, self.networkPos, nodelist=redNodes, node_color="r", linewidths=2) if greenNodes: nx.draw_networkx_nodes(self.networkGraph, self.networkPos, nodelist=greenNodes, node_color="w", linewidths=2) if blackEdges: nx.draw_networkx_edges(self.networkGraph, self.networkPos, edgelist=blackEdges, edge_color="k", width=2, style='solid') if redEdges: nx.draw_networkx_edges(self.networkGraph, self.networkPos, edgelist=redEdges, edge_color="k", width=2, style='dotted') nx.draw_networkx_labels(self.networkGraph, self.networkPos) plt.figure("Domain").canvas.draw() plt.figure("Domain").canvas.flush_events()
def showDomain(self, a=0): s = self.state if self.networkGraph is None: # or self.networkPos is None: self.networkGraph = nx.Graph() # enumerate all computer_ids, simulatenously iterating through # neighbors list and compstatus for computer_id, (neighbors, compstatus) in enumerate(zip(self.NEIGHBORS, s)): # Add a node to network for each computer self.networkGraph.add_node(computer_id, node_color="w") for uniqueEdge in self.UNIQUE_EDGES: self.networkGraph.add_edge( uniqueEdge[0], uniqueEdge[1], edge_color="k") # Add an edge between each neighbor self.networkPos = nx.circular_layout(self.networkGraph) nx.draw_networkx_nodes( self.networkGraph, self.networkPos, node_color="w") nx.draw_networkx_edges( self.networkGraph, self.networkPos, edges_color="k") nx.draw_networkx_labels(self.networkGraph, self.networkPos) plt.show() else: plt.clf() blackEdges = [] redEdges = [] greenNodes = [] redNodes = [] for computer_id, (neighbors, compstatus) in enumerate(zip(self.NEIGHBORS, s)): if(compstatus == self.RUNNING): greenNodes.append(computer_id) else: redNodes.append(computer_id) # Iterate through all unique edges for uniqueEdge in self.UNIQUE_EDGES: if(s[uniqueEdge[0]] == self.RUNNING and s[uniqueEdge[1]] == self.RUNNING): # Then both computers are working blackEdges.append(uniqueEdge) else: # If either computer is BROKEN, make the edge red redEdges.append(uniqueEdge) # "if redNodes", etc. - only draw things in the network if these lists aren't empty / null if redNodes: nx.draw_networkx_nodes( self.networkGraph, self.networkPos, nodelist=redNodes, node_color="r", linewidths=2) if greenNodes: nx.draw_networkx_nodes( self.networkGraph, self.networkPos, nodelist=greenNodes, node_color="w", linewidths=2) if blackEdges: nx.draw_networkx_edges( self.networkGraph, self.networkPos, edgelist=blackEdges, edge_color="k", width=2, style='solid') if redEdges: nx.draw_networkx_edges( self.networkGraph, self.networkPos, edgelist=redEdges, edge_color="k", width=2, style='dotted') nx.draw_networkx_labels(self.networkGraph, self.networkPos) plt.draw()