def __init__(self,initial_module=None, name=None, logger=None):
     self.modules=dict()
     self.exterior_objects=[]
     self.resources=ResourceBundle()
     self.paths=nx.Graph()
     self.tasks=TaskTracker()
     self.actors=dict()
     self.name = name if name else "GenericStation"
     self.logger = logging.getLogger(logger.name + '.' + self.name) if logger else util.generic_logger        
     
     if initial_module: self.berth_module(None,None,initial_module,None)                        
Beispiel #2
0
    def __init__(self,initial_module=None, name=None, logger=None, mission_control = None):
        self.modules=dict()
        self.id = util.register(self)
        self.exterior_objects=[]
        self.resources=ResourceBundle()
        self.paths=nx.Graph()
        self.tasks=TaskTracker()
        self.actors=dict()
        self.name = name if name else "GenericStation"
        self.logger = logging.getLogger(logger.name + '.' + self.name) if logger else util.generic_logger        
        self.loggername = self.logger.name
        
        self.docked_stations = []

        self.location = 'LEO'
        self.position = 'Approach'
        
        self.mission_control = mission_control
        
        self.sprite = None
        self.refresh_image()
        
        if initial_module: self.dock_module(None,None,initial_module,None)                        
Beispiel #3
0
class Station():
    def __init__(self,initial_module=None, name=None, logger=None, mission_control = None):
        self.modules=dict()
        self.id = util.register(self)
        self.exterior_objects=[]
        self.resources=ResourceBundle()
        self.paths=nx.Graph()
        self.tasks=TaskTracker()
        self.actors=dict()
        self.name = name if name else "GenericStation"
        self.logger = logging.getLogger(logger.name + '.' + self.name) if logger else util.generic_logger        
        self.loggername = self.logger.name
        
        self.docked_stations = []

        self.location = 'LEO'
        self.position = 'Approach'
        
        self.mission_control = mission_control
        
        self.sprite = None
        self.refresh_image()
        
        if initial_module: self.dock_module(None,None,initial_module,None)                        

    def __getstate__(self):
        d = dict(self.__dict__)
        del d['logger']
        return d    
        
    def __setstate__(self, d):
        self.__dict__.update(d)   
        self.logger = logging.getLogger(self.loggername) if self.loggername else util.generic_logger    
                       
    def refresh_image(self):
        if util.GRAPHICS == 'cocos2d':
            if self.sprite is None:               
                self.sprite = util.Layer()
                       
    def dock_module(self, my_module, my_dock, module, mod_dock, instant = False):        
        if module and not self.modules:
            self.modules[module.id]=module
            module.station = self
            module.refresh_station()
            self.paths = module.paths.copy()
            self.position = 'Docked'
            return
            
        if not my_module: my_module = random.choice( [ self.modules[m] for m in self.modules if self.modules[m].get_random_dock() ] )    
        if not my_module.id in self.modules: assert False, "Requested module not part of station"
        if module.id in self.modules: assert False, "Requested new module already part of station"
                
        if not my_dock: my_dock = my_module.get_random_dock()                 
        if not mod_dock: mod_dock = module.get_random_dock(side_port_allowed=False)                                        
                
        #attempt docking
        assert module.dock(mod_dock, my_module, my_dock)
        
        if module.station != self and not module.station in self.docked_stations:
            #merge stations
            other_station = module.station
            
            n=self.paths.nodes()
            e=self.paths.edges(data=True)
            
            self.paths.add_nodes_from(other_station.paths.nodes())
            self.paths.add_edges_from(other_station.paths.edges(data=True))
            other_station.paths.add_nodes_from(n)
            other_station.paths.add_edges_from(e)
            
            self.docked_stations.append(other_station)
            other_station.docked_stations.append(self)
                
        module.connect(mod_dock, my_module, my_dock, instant)        
        
        #remove if hanging outside
        if module in self.exterior_objects: self.exterior_objects.remove(module)
        
        #merge resources
        self.resources.grow()
        
        self.modules[module.id]=module  
        self.logger.info(''.join(["Modules berthed: ",my_module.short_id,'(',my_dock,')',' to ',module.short_id,'(',mod_dock,')']))
        
    def join_station(self, other_station):          
        if not other_station in self.docked_stations:
            self.logger.warning('Attempting to join two stations that are apparently not docked.')
            
        for m in other_station.modules.keys():
            other_station.modules[m].station = self
            other_station.modules[m].refresh_station()
            if not m in self.modules:
                self.modules[m] = other_station.modules[m]
            else:
                self.modules[other_station.modules[m].id] = other_station.modules[m]
            other_station.modules.pop(m)
                    
        for a in other_station.actors.keys():
            other_station.actors[a].station = self
            self.actors[a] = other_station.actors[a]
            self.actors[a].refresh_station()
            other_station.actors.pop(a)
            
        if other_station in self.docked_stations: 
            self.docked_stations.remove(other_station)


    def percolate_location(self,init_mod):
        self.reset_module_touches()
        init_mod.percolate_location()
        
    
    def split_station(self, docking_ring):
        '''Splits off the module WITH the given docking ring into a new station, percolates it to connected modules'''
        if not docking_ring or not docking_ring.installed or not docking_ring.docked: return
        self.reset_module_touches()
        docking_ring.docked.touched = True
        new_station_list = docking_ring.installed.percolate()
        if len(new_station_list) == len(self.modules.values()) -1:
            self.logger.warning(''.join(["Attempting to split a doubly or-higher connected module from station"])) 
            pass
            
        #Validate new station
        for n in new_station_list:
            if n.manifest and not n.manifest.satisfied:
                self.logger.info("Station splitting failed: at least one split module has unsatisfied manifest!")
                return False    
            
        new_station = Station(None, "Return Station", self.logger)
        new_station.position='Docked'
        self.docked_stations.append(new_station)
        new_station.docked_stations.append(self)
        new_station.paths.add_nodes_from(self.paths.nodes())
        new_station.paths.add_edges_from(self.paths.edges(data=True))
                     
        util.scenario.add_station(new_station)
        
        for a in self.actors.keys():
            if self.get_module_from_loc(self.actors[a].location) in new_station_list:
                self.actors[a].station = new_station
                new_station.actors[a] = self.actors[a]
                self.actors[a].refresh_station()
                self.actors.pop(a)
        
        for m in new_station_list:
            m.station = new_station
            new_station.modules[m.id] = m
            m.refresh_station()
            self.modules.pop(m.id)
                                                            
        self.logger.info(''.join(["Successfully split station! New station: ",util.short_id(new_station.id)]))
        
        return new_station

    def undock_station(self,other_station):
        if other_station == self: return
        if other_station in self.docked_stations: 
            self.docked_stations.remove(other_station)
        else:
            return
        
        #prune nodes, edges
        for n in self.paths.nodes(): 
            if self.get_module_from_loc(n) == None:
                self.paths.remove_node(n)
        for e in self.paths.edges():
            if not (e[0] in self.paths and e[1] in self.paths):
                self.paths.remove_edge(e)
                
        other_station.undock_station(self)
        
    def reset_module_touches(self):
        for m in self.modules.values():
            m.touched=False

    def get_safe_distance_orient(self):
        return np.array([-30,-30+60*random.random(),0]), np.array([ -math.pi +2*math.pi*random.random(), 0 ])

    def position_at_safe_distance(self,module):
        station=None
        if isinstance(module, Station):
            station = module
            module = module.modules.values()[0]
        #TODO calculate boundary of station, multiply by 1.25
        safe_location, safe_orient = self.get_safe_distance_orient()
        
        module.location = 2*safe_location
        module.orientation = safe_orient
        
        if station is not None:
            station.percolate_location(module)
        
        if not module.station: self.exterior_objects.append(module)
        module.refresh_image()                
        
        
    def begin_docking_approach(self,module,dock=None):                
        dock_comp, d, d = self.search( EquipmentFilter( target='Docking Computer' ) )
        if not dock_comp:
            #TODO fail more gracefully
            assert False, 'Docking initialized with no active docking computer!  WTF mang?'
        dock_comp.dock_module([module,dock],[None,None])

    def begin_undocking_approach(self,module,dock=None):                
        dock_comp, d, d = self.search( EquipmentFilter( target='Docking Computer' ) )
        if not dock_comp:
            #TODO fail more gracefully
            assert False, 'Undocking initialized with no active docking computer!  WTF mang?'
        dock_comp.undock_module([module,dock])

    def get_random_dock(self, side_port_allowed = True, modules_to_exclude=[]):
        hits=[]
        for m in [n for n in self.modules.values() if not n in modules_to_exclude]:
            d = m.get_random_dock( side_port_allowed )
            if d: hits.append( [ m, d ] )    
        random.shuffle(hits)  
        hits.sort(key=lambda tup: tup[0], reverse=True)
        return hits[0] if hits else [None, None]              
        
        
    def search(self, filter_, modules_to_exclude=[]):
        hits=[]
        if [m for m in self.modules.values() if not m in modules_to_exclude] == []:
            return [None, None, None]        
        for m in [n for n in self.modules.values() if not n in modules_to_exclude]:
            [obj, loc, score] = m.search(filter_)
            hits.append( [ obj, loc, score ] )
        random.shuffle(hits)    
        hits.sort(key=lambda tup: tup[2], reverse=True)
        #print hits
        return hits[0] if hits and hits[0][2] else [None, None, None]
        
        
    def random_location(self, modules_to_exclude=[]):        
        if [m for m in self.modules.values() if not m in modules_to_exclude] == []:
            return [None, None, None]
        module = random.choice([m for m in self.modules.values() if not m in modules_to_exclude])
        return [None, module.filterNode( module.node('Inside') ), None]
        
    def update(self,dt):
        self.resources.update(dt)
        self.tasks.update(dt)
        
        #print [[t.name,str(t.touched)] for t in self.tasks.tasks]
        for m in self.modules.keys():
            if m in self.modules: self.modules[m].update(dt)     
        for a in self.actors.values():
            a.update(dt)      
        
            
    def loc_to_xyz(self,loc, percolate=True):
        [ node, name ] = separate_node(loc)
        module = self.get_module_from_loc(loc, percolate)
        if name == "Inside": return module.location
        return module.getXYZ(module.nodes[loc])
        
    def xyz_to_module(self, xyz):
        pass      #needs collision detection
        
    def get_module_from_loc(self, loc, percolate=True):
        [ node, name ] = separate_node( loc )
        module = [ self.modules[ m ] for m in self.modules if self.modules[ m ].id == node ]        
        if not module: 
            if percolate:
                for s in self.docked_stations:
                    new_loc = s.get_module_from_loc(loc,False)
                    if new_loc != None: return new_loc
            return None
        return module[ 0 ]
        
    def draw(self, window):
        if not window: return self.logger.warning("Requested draw to Nonetype.")
        for m in self.exterior_objects:
            m.draw(window)
        for m in self.modules.values():
            m.draw(window)
        for a in self.actors:
            self.actors[a].update_location()
            self.actors[a].sprite.draw()
class Station():
    def __init__(self,initial_module=None, name=None, logger=None):
        self.modules=dict()
        self.exterior_objects=[]
        self.resources=ResourceBundle()
        self.paths=nx.Graph()
        self.tasks=TaskTracker()
        self.actors=dict()
        self.name = name if name else "GenericStation"
        self.logger = logging.getLogger(logger.name + '.' + self.name) if logger else util.generic_logger        
        
        if initial_module: self.berth_module(None,None,initial_module,None)                        
                       
    def berth_module(self, my_module, my_dock, module, mod_dock, instant = False):        
        if module and not self.modules:
            self.modules[module.id]=module
            module.station = self
            module.refresh_equipment()
            self.paths = module.paths.copy()
            return
            
        if not my_module: my_module = random.choice( [ self.modules[m] for m in self.modules if self.modules[m].get_random_dock() ] )    
        if not my_module.id in self.modules: assert False, "Requested module not part of station"
        if module.id in self.modules: assert False, "Requested new module already part of station"
                
        if not my_dock: my_dock = my_module.get_random_dock()                 
        if not mod_dock: mod_dock = module.get_random_dock(side_port_allowed=False)                                        
                
        #attempt docking
        assert module.berth(mod_dock, my_module, my_dock, instant)
        
        #remove if hanging outside
        if module in self.exterior_objects: self.exterior_objects.remove(module)
        
        #merge resources
        self.resources.grow()
        
        self.modules[module.id]=module  
        self.logger.info(''.join(["Modules berthed: ",my_module.short_id,'(',my_dock,')',' to ',module.short_id,'(',mod_dock,')']))
        
        
    def begin_docking_approach(self,module):
        #TODO calculate boundary of station, multiply by 1.25
        safe_location = np.array([-30,-30+60*random.random(),0])
        
        module.location = safe_location
        module.orientation = np.array([ -math.pi +2*math.pi*random.random(), 0 ])
        
        self.exterior_objects.append(module)
        module.refresh_image()
        
        dock_comp, d, d = self.search( EquipmentFilter( target='Docking Computer' ) )
        if not dock_comp:
            #TODO fail more gracefully
            assert False, 'Docking initialized with no active docking computer!  WTF mang?'
        dock_comp.dock_module([module,None],[None,None])

            
        
    def search(self, filter_):
        hits=[]
        for m in self.modules.values():
            [obj, loc, score] = m.search(filter_)
            hits.append( [ obj, loc, score ] )
        random.shuffle(hits)    
        hits.sort(key=lambda tup: tup[2], reverse=True)
        #print hits
        return hits[0] if hits and hits[0][2] else [None, None, None]
        
    def random_location(self):
        module = random.choice(self.modules.values())
        return None, module.filterNode( module.node('Inside') ), None
        
    def update(self,dt):
        self.resources.update(dt)
        self.tasks.update(dt)
        for m in self.modules:
            self.modules[m].update(dt)     
        for a in self.actors:
            self.actors[a].update(dt)       
            
    def loc_to_xyz(self,loc):
        [ node, name ] = separate_node(loc)
        module = [self.modules[m] for m in self.modules if self.modules[m].id == node]
        if not module: return None
        module = module[0]
        if name == "Inside": return module.location
        return module.getXYZ(module.nodes[loc])
        
    def xyz_to_module(self, xyz):
        pass      #needs collision detection
        
    def get_module_from_loc(self, loc):
        [ node, name ] = separate_node( loc )
        module = [ self.modules[ m ] for m in self.modules if self.modules[ m ].id == node ]        
        if not module: return None
        return module[ 0 ]
        
    def draw(self, window):
        if not window: return self.logger.warning("Requested draw to Nonetype.")
        for m in self.exterior_objects:
            m.draw(window)
        for m in self.modules.values():
            m.draw(window)
        for a in self.actors:
            self.actors[a].draw(window)