From 66e28b16233c394065ecb8f749c5c5041d7b2289 Mon Sep 17 00:00:00 2001 From: oxrock Date: Thu, 13 Feb 2020 00:42:14 -0500 Subject: [PATCH 1/2] Created an action chain class to make it easier to perform actions in sequence to perform a manuever, like a front flip. --- src/util/action_chain.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/util/action_chain.py diff --git a/src/util/action_chain.py b/src/util/action_chain.py new file mode 100644 index 0000000..2a192f3 --- /dev/null +++ b/src/util/action_chain.py @@ -0,0 +1,23 @@ + +class Action_chain(): + #class for performing consecutive actions over a period of time. Example: Flipping forward + def __init__(self, controls_list: list, durations_list : list): + self.controls = controls_list + self.durations = durations_list + self.complete = False + self.index = 0 + self.current_duration = 0 + # there should be a duration in the durations for every controller given in the list. This inserts 0 for any lacking + if len(durations_list) < len(controls_list): + self.durations+= [0*len(controls_list)-len(durations_list)] + + def update(self, time_increment : float): #call this once per frame with delta time to recieve updated controls + self.current_duration += time_increment + if self.current_duration > self.durations[self.index]: + self.index+=1 + self.current_duration = 0 + if self.index == len(self.controls): + self.complete = True + return self.controls[-1] + + return self.controls[self.index] From e878c4190f4c3a0cabbd0aac871a34bcfae09b79 Mon Sep 17 00:00:00 2001 From: oxrock Date: Thu, 13 Feb 2020 00:44:44 -0500 Subject: [PATCH 2/2] Added a function that parses ball prediction and returns the vector and time of the first predicted scoring ball. Added that information to debug rendering function. Also included an example of how to perform a front flip utilized the Action_chain class and included it into the current routine at a set interval. --- src/bot.py | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/src/bot.py b/src/bot.py index 58511a2..cb1cd94 100644 --- a/src/bot.py +++ b/src/bot.py @@ -5,6 +5,7 @@ from util.orientation import Orientation from util.vec import Vec3 +from util.action_chain import Action_chain class MyBot(BaseAgent): @@ -12,8 +13,21 @@ class MyBot(BaseAgent): def initialize_agent(self): # This runs once before the bot starts up self.controller_state = SimpleControllerState() + self.ball_predictions = None + self.current_action_chain = None + self.time = 0 + self.delta_time = 0 def get_output(self, packet: GameTickPacket) -> SimpleControllerState: + self.delta_time = packet.game_info.seconds_elapsed-self.time + self.time = packet.game_info.seconds_elapsed + self.ball_predictions = self.get_ball_prediction_struct() + predicted_goal = find_future_goal(self.ball_predictions) + goal_text = "No Goal Threats" + + if predicted_goal: + goal_text = f"Goal in {'%.4s' % str(predicted_goal[1]-packet.game_info.seconds_elapsed)}s" + ball_location = Vec3(packet.game_ball.physics.location) my_car = packet.game_cars[self.index] @@ -38,7 +52,16 @@ def get_output(self, packet: GameTickPacket) -> SimpleControllerState: self.controller_state.throttle = 1.0 self.controller_state.steer = turn - draw_debug(self.renderer, my_car, packet.game_ball, action_display) + draw_debug(self.renderer, my_car, packet.game_ball, action_display,goal_text) + + if self.current_action_chain != None: + if not self.current_action_chain.complete: + self.controller_state = self.current_action_chain.update(self.delta_time) + else: + self.current_action_chain = None + else: + if int(self.time) % 5 == 0: + self.current_action_chain = simple_front_flip_chain() return self.controller_state @@ -62,10 +85,39 @@ def find_correction(current: Vec3, ideal: Vec3) -> float: return diff -def draw_debug(renderer, car, ball, action_display): + +def draw_debug(renderer, car, ball, action_display,goal_text): renderer.begin_rendering() # draw a line from the car to the ball renderer.draw_line_3d(car.physics.location, ball.physics.location, renderer.white()) # print the action that the bot is taking renderer.draw_string_3d(car.physics.location, 2, 2, action_display, renderer.white()) + renderer.draw_string_2d(100, 50, 3, 3, goal_text, renderer.yellow()) renderer.end_rendering() + +def find_future_goal(ball_predictions): + for i in range(0, ball_predictions.num_slices): + if abs(ball_predictions.slices[i].physics.location.y) >= 5235: #field length(5120) + ball radius(93) = 5213 however that results in false positives + #returns the position the ball crosses the goal as well as the time it's predicted to occur + return [Vec3(ball_predictions.slices[i].physics.location),ball_predictions.slices[i].game_seconds] + + return None + +def simple_front_flip_chain(): + first_controller = SimpleControllerState() + second_controller = SimpleControllerState() + third_controller = SimpleControllerState() + + first_controller.jump = True + first_duration = 0.1 + + second_controller.jump = False + second_controller.pitch = -1 + second_duration = 0.1 + + third_controller.jump = True + third_controller.pitch = -1 + third_duration = 0.1 + + return Action_chain([first_controller,second_controller,third_controller],[first_duration,second_duration, + third_duration]) \ No newline at end of file