def execute_running(self): # checks if there is an offensive behavior for the various plays and set the normal speed for sub in self.subbehaviors_by_name(): if (sub != 'passer'): robo = self.subbehavior_with_name(sub).robot # checks if there is a chasing robot and set their speed to defense speed if (robo != None): if (sub == 'chasing'): robo.set_max_speed(self.defense_speed) # otherwise sets to the offensive normal speed rate else: robo.set_max_speed(self.normal_speed) # chasing robot positon should always follow the ball within a smaller inside box of the # four corners. if (self.has_subbehavior_with_name('chasing')): self.chaser.pos = self.cut_off_pos(main.ball().pos) #draw the four courner field # takes in the square points and form lines and create a square on the field for i in range(len(self.square_points)): main.debug_drawer().draw_line( robocup.Line(self.square_points[i], self.square_points[(i + 1) % 4]), (135, 0, 255), "Square") # speed of the hunting robots #TODO Create python pull from Config values. Currently this breaks the world. #tmp = copy.deepcopy(robocup.Configuration.FromRegisteredConfigurables().nameLookup("MotionConstraints/Max Velocity").value) self.normal_speed = 1.0 # tmp #speed of the defending robots can decrease value to make it easier for offense self.defense_speed = 2 * self.normal_speed / 3.0 #self.normal_speed/2.0#self.variable_square/(min(self.width,self.length) * 2) * self.normal_speed
def execute_setup(self): move_goal = main.ball().pos - self._target_line.delta().normalized( ) * (self.drive_around_dist + constants.Robot.Radius) left_field_edge = robocup.Segment( robocup.Point( -constants.Field.Width / 2.0 - constants.Robot.Radius, 0), robocup.Point( -constants.Field.Width / 2.0 - constants.Robot.Radius, constants.Field.Length)) right_field_edge = robocup.Segment( robocup.Point(constants.Field.Width / 2.0 + constants.Robot.Radius, 0), robocup.Point(constants.Field.Width / 2.0 + constants.Robot.Radius, constants.Field.Length)) # handle the case when the ball is near the field's edge field_edge_thresh = 0.3 behind_line = robocup.Segment( main.ball().pos - self._target_line.delta().normalized() * self.drive_around_dist, main.ball().pos - self._target_line.delta().normalized()) main.debug_drawer().draw_line(behind_line, constants.Colors.Blue, "LineKickOld") for edge in [left_field_edge, right_field_edge]: if edge.near_point(main.ball().pos, field_edge_thresh): intersection = behind_line.segment_intersection(edge) if intersection != None: move_goal = intersection self.robot.set_avoid_ball_radius(self.setup_ball_avoid) self.robot.move_to(move_goal) self.robot.face(self.robot.pos + (self.aim_target_point - main.ball().pos)) self.robot.unkick()
def execute_charge(self): self.robot.disable_avoid_ball() main.debug_drawer().draw_line( robocup.Line(self.robot.pos, self.aim_target_point), constants.Colors.White, "LineKickOld") main.debug_drawer().draw_line( robocup.Line(main.ball().pos, self.aim_target_point), constants.Colors.White, "LineKickOld") # drive directly into the ball ball2target = (self.aim_target_point - main.ball().pos).normalized() robot2ball = (main.ball().pos - self.robot.pos).normalized() speed = min(self.robot.vel.mag() + LineKickOld.AccelBias, self.MaxChargeSpeed) self.robot.set_world_vel(robot2ball.normalized() * speed) self.robot.face(self.aim_target_point) if main.ball().pos.dist_to( self.robot.pos) < LineKickOld.ClosenessThreshold: self._got_close = True if self.robot.has_ball(): if self.use_chipper: self.robot.chip(self.chip_power) else: self.robot.kick(self.kick_power)
def in_shot_triangle(self, best_point, alt_point): # get the two points of the enemies goal goalSegment = constants.Field.TheirGoalSegment right_post = goalSegment.get_pt(0) left_post = goalSegment.get_pt(1) # draw the line from the ideal passing position to the goal corners main.debug_drawer().draw_line( robocup.Line(right_post, best_point), (255, 0, 255), "Shot Range") main.debug_drawer().draw_line( robocup.Line(left_post, best_point), (255, 0, 255), "Shot Range") # angle between the line from ideal pass point and the goal corner and between the line ideal pass point and other goal corner shot_angle = (right_post - best_point).angle_between((left_post - best_point)) # angle between the line from ideal pass point and goal corner 1 and between the line from ideal pass point and 2nd best pass point left_post_alt_pos_angle = (best_point - alt_point).angle_between(best_point - right_post) # angle between the line from ideal pass point and goal corner 2 and between the line from ideal pass point and 2nd best pass point right_post_alt_pos_angle = (best_point - alt_point).angle_between(best_point - left_post) # decides which side is closer to point by the smaller theta if left_post_alt_pos_angle < right_post_alt_pos_angle: self.closest_post = left_post else: self.closest_post = right_post # if interior angles near sum to 0 then robot is inside the the zone. return abs(shot_angle - left_post_alt_pos_angle - right_post_alt_pos_angle) < self.epsilon
def execute_running(self): #pylint: disable=no-member if self.robot is not None and main.ball().valid: if self.shape_constraint is None: self.target_pos = self.ball_line().nearest_point( self.robot.pos) elif isinstance(self.shape_constraint, robocup.Segment): self.target_pos = self.shape_constraint.segment_intersection( self.ball_line()) if self.target_pos is None: self.target_pos = self.ball_line().nearest_point( self.robot.pos) self.target_pos = self.shape_constraint.nearest_point( self.target_pos) main.debug_drawer().draw_line(self.shape_constraint, (0, 255, 0), "Debug") else: self.target_pos = self.ball_line().nearest_point( self.robot.pos) # Intercept works better at high accelerations and speeds # but due to lag with bad motion control, it doesn't actually # end up moving robots in the way # TODO(motion-control): Swap back to intercept #self.robot.intercept(self.target_pos) self.robot.move_to(self.target_pos) if self.faceBall: self.robot.face(main.ball().pos)
def execute_aiming(self): self.set_aim_params() if isinstance(self.target, robocup.Segment): for i in range(2): main.debug_drawer().draw_line( robocup.Line(main.ball().pos, self.target.get_pt(i)), constants.Colors.Blue, "PivotKick")
def execute_running(self): self.recalculate() if self._pass_line != None: main.debug_drawer().draw_line(self._pass_line, constants.Colors.Blue, "Pass") main.debug_drawer().draw_circle(self._target_pos, 0.03, constants.Colors.Blue, "Pass")
def execute_running(self): super().execute_running() self.recalculate() self.robot.face(self.robot.pos + robocup.Point( math.cos(self._angle_facing), math.sin(self._angle_facing))) if self._kick_line != None: main.debug_drawer().draw_line(self._kick_line, constants.Colors.Red, "Shot")
def execute_kicker_forbidden(self): bot = None for b in main.our_robots(): if b.shell_id() == self.kicker_shell_id: bot = b break if self.kicker_shell_id and bot: main.debug_drawer().draw_text("Blocking double touch!", bot.pos, constants.Colors.Red, "Double Touches")
def calculate_shot_chance(self, robot): shot_position, success_chance = self.kick_eval.eval_pt_to_our_goal( robot.pos) if self.debug is True: shot_line = robocup.Segment(robot.pos, shot_position) main.debug_drawer().draw_line(shot_line, (0, 255, 0), "Target Position") main.debug_drawer().draw_text( "Shot Chance: " + str(success_chance), shot_line.center(), constants.Colors.White, "Defense") return success_chance
def execute_receiving(self): super().execute_receiving() self.ball_kicked = True # Kick the ball! if (self.robot is not None and evaluation.ball.robot_has_ball( self.robot)): #self.robot.has_ball()): # self.robot.kick(self.kick_power) self.robot.kick_immediately() if self.target_point != None: main.debug_drawer().draw_circle(self.target_point, 0.03, constants.Colors.Blue, "Target")
def execute_running(self): # draw laps # indices = list(range(len(self.points))) + [0] # for i in range(len(indices)): main.debug_drawer().draw_line( robocup.Line(self.points[0], self.points[1]), (255, 0, 0), "StressTest") m = self.subbehavior_with_name('move') if m.state == behavior.Behavior.State.completed: # increment index self.index = (self.index + 1) % len(self.points) m.pos = self.points[self.index]
def block_line(self, value): self._block_line = value # we move somewhere along this arc to mark our 'block_line' offset = constants.Robot.Radius * self._defend_goal_radius left_seg = robocup.Segment( robocup.Point(-constants.Field.PenaltyLongDist / 2 - offset, 0), robocup.Point(-constants.Field.PenaltyLongDist / 2 - offset, constants.Field.PenaltyShortDist + offset)) right_seg = robocup.Segment( robocup.Point(constants.Field.PenaltyLongDist / 2 + offset, 0), robocup.Point(constants.Field.PenaltyLongDist / 2 + offset, constants.Field.PenaltyShortDist + offset)) top_seg = robocup.Segment( robocup.Point(-constants.Field.PenaltyLongDist / 2 - offset, constants.Field.PenaltyShortDist + offset), robocup.Point(constants.Field.PenaltyLongDist / 2 + offset, constants.Field.PenaltyShortDist + offset)) default_pt = top_seg.center() if self._block_line is not None: # main.debug_drawer().draw_line(self._block_line, constants.Colors.White, "SubmissiveDefender") main.debug_drawer().draw_circle(self._block_line.get_pt(0), 0.1, constants.Colors.White, "SubmissiveDefender") threat_point = self._block_line.get_pt(0) intersection_center = top_seg.line_intersection(self._block_line) if threat_point.x < 0: intersections_left = left_seg.line_intersection( self._block_line) if intersections_left is not None: self._move_target = intersections_left elif intersection_center is not None: self._move_target = intersection_center else: self._move_target = default_pt elif threat_point.x >= 0: intersections_right = right_seg.line_intersection( self._block_line) if intersections_right is not None: self._move_target = intersections_right elif intersection_center is not None: self._move_target = intersection_center else: self._move_target = default_pt else: self._move_target = default_pt
def facing_opp_goal(self): robot = self.subbehavior_with_name('aim').robot if robot is None: return False # L is left post # R is right post # T is target aiming point # U is us # L T R # \ | / # \ | / # \ | / # \ | / # \|/ # U # Angle LUT + Angle RUT should equal Angle LUR if vector UT is between vectors UL and UR # # # L R T # \ | / # \ | / # \ | / # \ | / # \|/ # U # Here, Angle LUT + Angle RUT is much larger than Angle LUR since vector UT is outside vectors UL and UR left_goal_post = robocup.Point(-constants.Field.GoalWidth / 2, constants.Field.Length) right_goal_post = robocup.Point(constants.Field.GoalWidth / 2, constants.Field.Length) bot_to_left_goal_post = left_goal_post - robot.pos bot_to_right_goal_post = right_goal_post - robot.pos bot_forward_vector = robot.pos + robocup.Point(math.cos(robot.angle), math.sin(robot.angle)) angle_left_goal_post_diff = bot_forward_vector.angle_between( bot_to_left_goal_post ) angle_right_goal_post_diff = bot_forward_vector.angle_between( bot_to_right_goal_post ) angle_goal_post_diff = bot_to_left_goal_post.angle_between( bot_to_right_goal_post ) # Add a small amount for any errors in these math functions small_angle_offset = 0.01 # We are aiming at the goal if (angle_left_goal_post_diff + angle_right_goal_post_diff + small_angle_offset <= angle_goal_post_diff): print('EARLY KIck') main.debug_drawer().draw_text('Early kick', robot.pos, 'PivotKick') return True return False
def execute_marking(self): move = self.subbehavior_with_name('move') move.pos = self.move_target left_seg = robocup.Segment( robocup.Point(-constants.Field.PenaltyLongDist / 2, 0), robocup.Point(-constants.Field.PenaltyLongDist / 2, constants.Field.PenaltyShortDist)) right_seg = robocup.Segment( robocup.Point(constants.Field.PenaltyLongDist / 2, 0), robocup.Point(constants.Field.PenaltyLongDist / 2, constants.Field.PenaltyShortDist)) top_seg = robocup.Segment( robocup.Point(-constants.Field.PenaltyLongDist / 2, constants.Field.PenaltyShortDist), robocup.Point(constants.Field.PenaltyLongDist / 2, constants.Field.PenaltyShortDist)) if move.pos is not None: main.debug_drawer().draw_circle(move.pos, 0.02, constants.Colors.Green, "Mark") main.debug_drawer().draw_segment(left_seg, constants.Colors.Green, "Mark") main.debug_drawer().draw_segment(top_seg, constants.Colors.Green, "Mark") main.debug_drawer().draw_segment(right_seg, constants.Colors.Green, "Mark") # make the defender face the threat it's defending against if (self.robot is not None and self.block_line is not None): self.robot.face(self.block_line.get_pt(0)) if self.robot.has_ball() and not main.game_state().is_stopped( ) and not self._self_goal(self.robot): self.robot.kick(0.75)
def execute_running(self): #pylint: disable=no-member #Skill does nothing if mark point isn't given AND the ball or robot to mark can't be found if self.mark_point is None and \ (self.mark_robot is None or not main.ball().valid or not self.mark_robot.visible): return #Sets the position to mark as the given mark position #or robot position if no mark position is given ball_pos = main.ball().pos pos = self.robot.pos mark_pos = self.mark_point if self.mark_point is not None else self.mark_robot.pos #Finds the line from the ball to the mark position and creates a line between them #removing the overlap with the ball on one side and robot on the other #This assumes even with mark position parameter that there is a robot there to avoid mark_line_dir = (ball_pos - mark_pos).normalized() ball_mark_line = robocup.Segment( ball_pos - mark_line_dir * constants.Ball.Radius, mark_pos + mark_line_dir * 2.0 * constants.Robot.Radius) #Drawing for simulator main.debug_drawer().draw_line(ball_mark_line, (0, 0, 255), "Mark") #Distance from robot to mark line mark_line_dist = ball_mark_line.dist_to(pos) #Sets target point to nearest point on mark line if the robot is over ball_mark_threshold #from the mark line # or #Sets target point to place on line defined by ratio- # - 0 being close to ball, 1 close to mark pt self._target_point = None if mark_line_dist > self.mark_line_thresh: self._target_point = ball_mark_line.nearest_point(pos) else: self._target_point = ball_pos + (mark_pos - ball_pos).normalized( ) * self.ratio * ball_mark_line.length() #Drawing for simulator main.debug_drawer().draw_circle(mark_pos, constants.Robot.Radius * 1.2, (0, 127, 255), "Mark") #Move robot into position and face the ball self.robot.move_to(self._target_point)
def display_visualization_points(values, show_max=True): num_width = len(values) num_length = len(values[0]) x_half = 0.5 * constants.Field.Width / num_width y_half = 0.5 * constants.Field.Length / num_length max_pt = robocup.Point(0, 0) max_val = 0 for x in range(-1 * round(num_width / 2), round(num_width / 2)): for y in range(0, num_length): x_cent = x * constants.Field.Width / num_width + x_half y_cent = y * constants.Field.Length / num_length + y_half val = values[0].pop(0) val = min(val, 1) val = max(val, 0) if (val > max_val): max_pt = robocup.Point(x_cent, y_cent) max_val = val rect = [ robocup.Point(x_cent - x_half, y_cent - y_half), robocup.Point(x_cent + x_half, y_cent - y_half), robocup.Point(x_cent + x_half, y_cent + y_half), robocup.Point(x_cent - x_half, y_cent + y_half) ] # Linear interpolation between Red and Blue val_color = (round(val * 255), 0, round((1 - val) * 255)) # Draw onto the Overlay layer main.debug_drawer().draw_polygon(rect, val_color, "Overlay") values.pop(0) rect = [ robocup.Point(max_pt.x - x_half, max_pt.y - y_half), robocup.Point(max_pt.x + x_half, max_pt.y - y_half), robocup.Point(max_pt.x + x_half, max_pt.y + y_half), robocup.Point(max_pt.x - x_half, max_pt.y + y_half) ] # Make a white rect at the max value val_color = (255, 255, 255) # Draw onto the Max layer main.debug_drawer().draw_polygon(rect, val_color, "Max")
def eval_best_receive_point(kick_point, evaluation_zone=None, ignore_robots=[]): win_eval = robocup.WindowEvaluator(main.context()) for r in ignore_robots: win_eval.add_excluded_robot(r) targetSeg = constants.Field.TheirGoalSegment # Autogenerate kick point if evaluation_zone is None: evaluation_zone = generate_default_rectangle(kick_point) segments = get_segments_from_rect(evaluation_zone) if segments is None or len(segments) == 0: # We can't do anything. return None, None, None bestChance = None for segment in segments: main.debug_drawer().draw_line(segment, constants.Colors.Blue, "Candidate Lines") _, best = win_eval.eval_pt_to_seg(kick_point, segment) if best is None: continue currentChance = best.shot_success # TODO dont only aim for center of goal. Waiting on window_evaluator returning a probability. receivePt = best.segment.center() _, best = win_eval.eval_pt_to_seg(receivePt, targetSeg) if best is None: continue currentChance = currentChance * best.shot_success if bestChance is None or currentChance > bestChance: bestChance = currentChance targetPoint = best.segment.center() bestpt = receivePt if bestpt is None: return None, None, None return bestpt, targetPoint, bestChance
def execute_charge(self): main.debug_drawer().draw_line( robocup.Line(self.robot.pos, self.target), constants.Colors.White, "bump") main.debug_drawer().draw_line( robocup.Line(main.ball().pos, self.target), constants.Colors.White, "bump") ball2target = (self.target - main.ball().pos).normalized() drive_dir = (main.ball().pos - ball2target * constants.Robot.Radius) - self.robot.pos # we want to drive toward the ball without using the path planner # we do this by setting the speed directly # AccelBias forces us to accelerate a bit more speed = self.robot.vel.mag() + Bump.AccelBias self.robot.set_world_vel(drive_dir.normalized() * speed) self.robot.face(main.ball().pos)
def find_defense_positions(ignore_robots=[]): their_risk_scores = [] for bot in main.their_robots(): score = estimate_risk_score(bot.pos, ignore_robots) main.debug_drawer().draw_text("Risk: " + str(int(score * 100)), bot.pos, constants.Colors.White, "Defense") their_risk_scores.extend([score]) # Sorts bot array based on their score zipped_array = zip(their_risk_scores, main.their_robots()) sorted_array = sorted(zipped_array, reverse=True) sorted_bot = [bot for (scores, bot) in sorted_array] area_def_pos = create_area_defense_zones(ignore_robots) return area_def_pos, sorted_bot[0], sorted_bot[1]
def check_failure(self): # We wait about 3 frames before freezing the velocity and position of the ball # as it can be unreliable right after kicking. See execute_receiving. if self.stable_frame < PassReceive.StabilizationFrames: return False offset = 0.1 straight_line = robocup.Point(0, 1) pass_segment = self.robot.pos - self.kicked_from pass_distance = pass_segment.mag() + 0.5 pass_dir = pass_segment.normalized() left_kick = robocup.Point(-offset, -offset) right_kick = robocup.Point(offset, -offset) # Create a channel on the left/right of the mouth of the kicker to a bit behind the receiver left_recieve = left_kick + straight_line * pass_distance right_recieve = right_kick + straight_line * pass_distance # Widen the channel to allow for catching the ball. left_recieve.rotate(left_kick, PassReceive.MarginAngle) right_recieve.rotate(right_kick, -PassReceive.MarginAngle) origin = robocup.Point(0, 0) passDirRadians = pass_dir.angle() left_kick.rotate(origin, passDirRadians - math.pi / 2) right_kick.rotate(origin, passDirRadians - math.pi / 2) left_recieve.rotate(origin, passDirRadians - math.pi / 2) right_recieve.rotate(origin, passDirRadians - math.pi / 2) # Add points that create the good_area to a polygon good_area = robocup.Polygon() good_area.add_vertex(self.kicked_from + left_kick) good_area.add_vertex(self.kicked_from + right_kick) good_area.add_vertex(self.kicked_from + right_recieve) good_area.add_vertex(self.kicked_from + left_recieve) main.debug_drawer().draw_raw_polygon(good_area, constants.Colors.Green, "Good Pass Area") return not good_area.contains_point(main.ball().pos)
def execute_running(self): #Skill does nothing if mark point isn't given AND the ball or robot to mark can't be found if self.robot is None or (self.mark_point is None and \ (self.mark_robot is None or not main.ball().valid or not self.mark_robot.visible)): return #Finds the line from the mark position to the shot point and creates a line between them #removing the overlap with the ball on one side and robot on the other #This assumes even with mark position parameter that there is a robot there to avoid self._reset_mark_pos() mark_line, shot_pt = self.get_mark_segment() #Drawing for simulator main.debug_drawer().draw_line(mark_line, (0, 0, 255), "Mark") #Distance from robot to mark line mark_line_dist = mark_line.dist_to(self.robot.pos) #Sets target point to nearest point on mark line if the robot is over ball_mark_threshold #from the mark line # or #Sets target point to place on line defined by ratio- # - 0 being close to ball, 1 close to mark pt self._target_point = None if mark_line_dist > self.mark_line_thresh: self._target_point = mark_line.nearest_point(self.robot.pos) else: self._target_point = self.adjusted_mark_pos - ( self.mark_pos - shot_pt).normalized() * self.ratio * mark_line.length() #Drawing for simulator main.debug_drawer().draw_circle(self.mark_pos, constants.Robot.Radius * 1.2, (0, 127, 255), "Mark") #Move robot into position and face the ball self.robot.move_to(self._target_point) self.robot.face(main.ball().pos)
def execute_lineup(self): target_line = self.target_line() target_dir = target_line.delta().normalized() behind_line = robocup.Segment( main.ball().pos - target_dir * (Bump.DriveAroundDist + constants.Robot.Radius), main.ball().pos - target_dir * 5.0) if target_line.delta().dot(self.robot.pos - main.ball().pos) > -constants.Robot.Radius: # we're very close to or in front of the ball self.robot.set_avoid_ball_radius(Bump.LineupBallAvoidRadius) self.robot.move_to(main.ball().pos - target_dir * (Bump.DriveAroundDist + constants.Robot.Radius)) else: self.robot.set_avoid_ball_radius(Bump.LineupBallAvoidRadius) self.robot.move_to(behind_line.nearest_point(self.robot.pos)) main.debug_drawer().draw_line(behind_line, constants.Colors.Black, "Bump") delta_facing = self.target - main.ball().pos self.robot.face(self.robot.pos + delta_facing)
def opp_robot_blocking(self): if (self.robot is None): return False # Closest opp robot in any direction # To us, not the ball closest_opp_robot = None closest_opp_dist = float("inf") for r in main.their_robots(): if ((r.pos - self.robot.pos).mag() < closest_opp_dist): closest_opp_robot = r closest_opp_dist = (r.pos - self.robot.pos).mag() # Only do this if a robot is in range robot_in_range = closest_opp_dist < .2 + 2 * constants.Robot.Radius aim_dir = robocup.Point.direction(self.robot.angle) robot_dir = (closest_opp_robot.pos - self.robot.pos) # Only trigger if they are infront of us robot_in_front = aim_dir.dot(robot_dir) > 0 closest_pt = robocup.Line( self.robot.pos, self.robot.pos + aim_dir).nearest_point(closest_opp_robot.pos) does_hit_robot = (closest_opp_robot.pos - closest_pt ).mag() < constants.Robot.Radius facing_their_side = robocup.Point.direction(self.robot.angle).y > 0 ret = (facing_their_side and robot_in_range and robot_in_front and does_hit_robot) if ret: print("Panic kick") main.debug_drawer().draw_text('panic kick', self.robot.pos, (255, 255, 255), 'PivotKick') return ret
def execute_block(self): opposing_kicker = evaluation.ball.opponent_with_ball() if opposing_kicker is not None: winEval = robocup.WindowEvaluator(main.context()) winEval.excluded_robots = [self.robot] best = winEval.eval_pt_to_our_goal(main.ball().pos)[1] if best is not None: shot_line = robocup.Line(opposing_kicker.pos, main.ball().pos) block_line = robocup.Line( robocup.Point( best.segment.get_pt(0).x - constants.Robot.Radius, constants.Robot.Radius), robocup.Point( best.segment.get_pt(1).x + constants.Robot.Radius, constants.Robot.Radius)) main.debug_drawer().draw_line(block_line, (255, 0, 0), "Debug") dest = block_line.line_intersection(shot_line) dest.x = min(Goalie.MaxX, dest.x) dest.x = max(-Goalie.MaxX, dest.x) self.robot.move_to(dest) return self.robot.move_to( robocup.Point(0, constants.Robot.Radius + Goalie.OFFSET))
def execute_running(self): if self.robot.has_ball(): self.startBallLocation = main.ball().pos self.recalculate() self.robot.set_max_speed(0.9) self.robot.set_max_accel(0.9) # slowly pivot toward the target #self.robot.set_max_angle_speed(4) self.robot.pivot(self._face_target) self.robot.set_dribble_speed(self.dribbler_power) # draw current shot line if self._shot_point != None: color = constants.Colors.Green if self.is_aimed( ) else constants.Colors.Red main.debug_drawer().draw_line( robocup.Line(self.robot.pos, self._shot_point), color, "Aim") main.debug_drawer().draw_circle(self._shot_point, 0.02, color, "Aim") # draw where we're supposed to be aiming if self.target_point != None: main.debug_drawer().draw_circle(self.target_point, 0.02, constants.Colors.Blue, "Aim") # If we are within X degrees of the target, start the fine timeout if (self.target_point is not None and self._fine_start == 0 and robocup.Point.direction( self.robot.angle).angle_between(self.target_point - self.robot.pos) < 45 * constants.DegreesToRadians and robocup.Point.direction( self.robot.angle).dot(self.target_point - self.robot.pos) > 0): self._fine_start = time.time()
def find_gap(target_pos=constants.Field.TheirGoalSegment.center(), max_shooting_angle=60, robot_offset=8, dist_from_point=.75): if (not main.ball().valid): return target_pos # Find the hole in the defenders to kick at # The limit is 20 cm so any point past it should be defenders right there win_eval = robocup.WindowEvaluator(main.context()) # 500 cm min circle distance plus the robot width test_distance = dist_from_point + constants.Robot.Radius # +- max offset to dodge ball max_angle = max_shooting_angle * constants.DegreesToRadians # How much left and right of a robot to give # Dont make this too big or it will always go far to the right or left of the robots robot_angle_offset = robot_offset * constants.DegreesToRadians zero_point = robocup.Point(0, 0) # Limit the angle so as we get closer, we dont miss the goal completely as much goal_vector = target_pos - main.ball().pos max_length_vector = robocup.Point(constants.Field.Length, constants.Field.Width) goal_limit = (goal_vector.mag() / max_length_vector.mag()) * max_angle # Limit on one side so we dont directly kick out of bounds # Add in the angle from the sideline to the target field_limit = (1 - abs(main.ball().pos.x) / (constants.Field.Width / 2)) * max_angle field_limit = field_limit + goal_vector.angle_between(robocup.Point(0, 1)) # Limit the angle based on the opponent robots to try and always minimize the left_robot_limit = 0 right_robot_limit = 0 for robot in main.their_robots(): ball_to_bot = robot.pos - main.ball().pos # Add an extra radius as wiggle room # kick eval already deals with the wiggle room so it isn't needed there if (ball_to_bot.mag() <= test_distance + constants.Robot.Radius): angle = goal_vector.angle_between(ball_to_bot) # Try and rotate onto the goal vector # if we actually do, then the robot is to the right of the ball vector ball_to_bot.rotate(zero_point, angle) if (ball_to_bot.angle_between(goal_vector) < 0.01): right_robot_limit = max(right_robot_limit, angle + robot_angle_offset) else: left_robot_limit = max(left_robot_limit, angle + robot_angle_offset) else: win_eval.add_excluded_robot(robot) # Angle limit on each side of the bot->goal vector left_angle = max_angle right_angle = max_angle # Make sure we limit the correct side due to the field if main.ball().pos.x < 0: left_angle = min(left_angle, field_limit) else: right_angle = min(right_angle, field_limit) # Limit due to goal left_angle = min(left_angle, goal_limit) right_angle = min(right_angle, goal_limit) # Limit to just over the robots if (left_robot_limit is not 0): left_angle = min(left_angle, left_robot_limit) if (right_robot_limit is not 0): right_angle = min(right_angle, right_robot_limit) # Get the angle that we need to rotate the target angle behind the defenders # since kick eval doesn't support a nonsymmetric angle around a target rotate_target_angle = (left_angle + -right_angle) / 2 target_width = (left_angle + right_angle) target_point = goal_vector.normalized() * test_distance target_point.rotate(zero_point, rotate_target_angle) windows, window = win_eval.eval_pt_to_pt(main.ball().pos, target_point + main.ball().pos, target_width) # Test draw points target_point.rotate(zero_point, target_width / 2) p1 = target_point + main.ball().pos target_point.rotate(zero_point, -target_width) p2 = target_point + main.ball().pos p3 = main.ball().pos main.debug_drawer().draw_polygon([p1, p2, p3], (0, 0, 255), "Free Kick search zone") is_opponent_blocking = False for robot in main.their_robots(): if (goal_vector.dist_to(robot.pos) < constants.Robot.Radius and (main.ball().pos - robot.pos).mag() < test_distance): is_opponent_blocking = True # Vector from ball position to the goal ideal_shot = (target_pos - main.ball().pos).normalized() # If on our side of the field and there are enemy robots around us, # prioritize passing forward vs passing towards their goal # Would have to change this if we are not aiming for their goal if main.ball().pos.y < constants.Field.Length / 2 and len(windows) > 1: ideal_shot = robocup.Point(0, 1) main.debug_drawer().draw_line(robocup.Line(main.ball().pos, target_pos), (0, 255, 0), "Target Point") # Weights for determining best shot k1 = 1.5 # Weight of closeness to ideal shot k2 = 1 # Weight of shot chance # Iterate through all possible windows to find the best possible shot if windows: best_shot = window.segment.center() best_weight = 0 for wind in windows: pos_to_wind = (wind.segment.center() - main.ball().pos).normalized() dot_prod = pos_to_wind.dot(ideal_shot) weight = k1 * dot_prod + k2 * wind.shot_success if weight > best_weight: best_weight = weight best_shot = wind.segment.center() main.debug_drawer().draw_line(robocup.Line(main.ball().pos, best_shot), (255, 255, 0), "Target Shot") best_shot = robocup.Point(0, 1) + main.ball().pos return best_shot else: return constants.Field.TheirGoalSegment.center()
def execute_placing(self): main.debug_drawer().draw_circle(self._pos, 0.1, constants.Colors.Green, "Place") main.debug_drawer().draw_circle(self._pos, 0.5, constants.Colors.Red, "Avoid")
def execute_running(self): main.debug_drawer().draw_circle(self.target, constants.Robot.Radius, constants.Colors.Green, "target")
def execute_setup(self): main.debug_drawer().draw_circle(self.move_point, 0.1, constants.Colors.Blue, "move setup")