def get_preferred_direction(self,beam): ''' Returns the preferred direction - this is the direction towards which the robot wants to move when looking for an already set support tube. The direction is a unit vector ''' # Calculate direction of repair (check 0 dist, which means it is perfectly # vertical!) i, j = beam.endpoints.i, beam.endpoints.j v1 = helpers.make_vector(self.location,j) v2 = helpers.make_vector(i,self.location) l1,l2 = helpers.length(v1), helpers.length(v2) # v1 is non-zero and it is not vertical if not (helpers.compare(l1,0) or helpers.is_vertical(v1)): return helpers.make_unit(v1) # v2 is non-zero and it is not vertical elif not (helpers.compare(l2,0) or helpers.is_vertical(v2)): return helpers.make_unit(v2) # No preferred direction because the beam is perfectly vertical else: return None
def filter_dict(self,dirs,new_dirs,comp_functions,preferenced,priorities=[]): ''' Filters a dictinary of directions, taking out all directions not in the correct directions based on the list of comp_functions (x,y,z). Edit: Now also filters on priority. If a direction has priority of 0, then it MUST be in that direction. The only way that it will ever return an empty dictionary is if none of the directions match the direction we want to move in for each coordinate with priority zero. Otherwise, we match as many low priorty numbers as possible. Same priorities must be matched at the same level. Edit: Have done mostly away with priorities, though for compatibility, we still keep them in case we want to use them later. Will probably work on removing them entirely. Now, we have added a "preferenced" bool which checks to see if the direction is within a specified angle of preferred travel (the angle is dictated in construction.py). The preference is set to True when we are searching for a support, otherwise to False. We want this direction, but if we can't find it, we reset the variable to False ''' # Access items for beam, vectors in dirs.items(): true_beam = self.structure.get_beam(beam,self.location) # If the beam won't be a support beam, pass it.. if (preferenced and true_beam.endpoints.j in true_beam.joints and self.memory['preferred_direction'] is not None): pass # Access each directions for vector in vectors: coord_bool = True # Apply each function to the correct coordinates for function, coord in zip(comp_functions,vector): coord_bool = coord_bool and function(coord) # Additionally, check the x-y direction if we have a preferenced direction if (preferenced and self.memory['preferred_direction'] is not None and not helpers.is_vertical(vector)): coord_bool = coord_bool and self.filter_preferred(vector) # Check to see if the direciton is acceptable and keep if it is if coord_bool: if beam not in new_dirs: new_dirs[beam] = [vector] else: new_dirs[beam].append(vector) # Special rules for travelling new_dirs = self.remove_specific(new_dirs) # Case is not matched, so obtain keys of max values and remove those # restraints if the value is not 0 if new_dirs == {}: # We didn't take priorities into account, now we do if priorities == []: # COPY the LIST priorities = list(self.memory['dir_priority']) max_val = max(priorities) # Set to -1 so we don't use them next time, and set comp_funs to True for i, val in enumerate(priorities): if val == max_val: priorities[i] = -1 comp_functions[i] = lambda a : True # We ran out of priorities and we have no preference, so just return the # empty set if max_val <= 0 and not preferenced: return new_dirs # We have preference, and/or priorites else: return self.filter_dict(dirs,new_dirs,comp_functions,False,priorities) # Non-empty set else: return new_dirs