def get_directions_info(self): ''' Returns a list of triplets with delta x, delta y, and delta z of the direction the robot can move in. These directions constitute the locations where beams currently exist. Additionally, it returns the "box of locality" to which the robot is restricted containing all of the beams nearby that the robot can detect (though, this should only be used for finding a connection, as the robot itself SHOULD only measure the stresses on its current beam) ''' # Run analysys before deciding to get the next direction if not self.model.GetModelIsLocked() and self.need_data(): errors = helpers.run_analysis(self.model) if errors != '': # pdb.set_trace() pass # Verify that the robot is on its beam and correct if necessary. # This is done so that floating-point arithmethic errors don't add up. (e1, e2) = self.beam.endpoints if not (helpers.on_line (e1,e2,self.location)): self.change_location(helpers.correct(e1,e2,self.location), self.beam) # Obtain all local objects box = self.structure.get_box(self.location) # Debugging if box == {}: # pdb.set_trace() pass # Find the beams and directions (ie, where can he walk?) directions_info = self.get_walkable_directions(box) return { 'box' : box, 'directions' : directions_info }
def addjoint(self, coord, beam): ''' Adds a joint (at the specified coordinate), to the beam itself. The beam variable defines the which crosses this one at the joint ''' # Verify that the coordinate is on the beam based on endpoints if not helpers.on_line(self.endpoints.i, self.endpoints.j, coord): return False else: coord = Coord(x=coord[0],y=coord[1],z=coord[2]) # We cycle manually so we can compare using our compare function for key, beams in self.joints.items(): # We have a key and the beam isn't already there if helpers.compare_tuple(key,coord) and beam not in beams: self.joints[key].append(beam) return True self.joints[coord] = [beam] return True
def support_beam_endpoint(self): ''' Returns the endpoint for a support beam ''' #pdb.set_trace() # Get broken beam e1,e2 = self.structure.get_endpoints(self.memory['broken_beam_name'], self.location) # Direction v = helpers.make_unit(helpers.make_vector(e1,e2)) # Get pivot and repair beam midpoint pivot = self.location midpoint1 = helpers.midpoint(e1,e2) # Upper midpoint to encourate upward building midpoint = helpers.midpoint(e2,midpoint1) # Add an offset to mimick inability to determine location exactly offset = helpers.scale(random.uniform(-1*variables.random,variables.random),v) midpoint = (helpers.sum_vectors(midpoint,offset) if random.randint(0,4) == 1 else midpoint) # Calculate starting beam_endpoint endpoint = helpers.beam_endpoint(pivot,midpoint) # Calculate angle from vertical angle_from_vertical = helpers.smallest_angle(helpers.make_vector(pivot, endpoint),(0,0,1)) # Get angles sorted_angles = self.local_angles(pivot,endpoint) min_support_angle,max_support_angle = self.get_angles() min_constraining_angle,max_constraining_angle = self.get_angles( support=False) # Defining here to have access to min,max, etc. def acceptable_support(angle,coord): # Find beam endpoints beam_endpoint = helpers.beam_endpoint(pivot,coord) # Calculate angle from vertical of beam we wish to construct based on the # information we've gathered from_vertical = (angle_from_vertical + angle if beam_endpoint[2] <= endpoint[2] else angle_from_vertical - angle) simple = not (from_vertical < min_constraining_angle or from_vertical > max_constraining_angle) # On the ground if self.beam is None: return simple # On a beam, so check our support_angle_difference else: beam_vector = helpers.make_vector(self.beam.endpoints.i, self.beam.endpoints.j) support_vector = helpers.make_vector(self.location,coord) angle = helpers.smallest_angle(beam_vector,support_vector) real_angle = abs(90-angle) if angle > 90 else angle return simple and real_angle > construction.beam['support_angle_difference'] return_coord = None for coord,angle in sorted_angles: if acceptable_support(angle,coord) and helpers.on_line(e1,e2,coord): self.memory['broken_beam_name'] = '' return coord elif acceptable_support(angle,coord): return_coord = coord if return_coord is not None: return return_coord else: # Otherwise, do default behaviour return super(Repairer,self).support_beam_endpoint()