def get_tap_time(self, sling, release, target, tap_interval): """finds the active bird, i.e., the one in the slingshot""" if tap_interval == 0: return 0 distance = target.X - sling.X r = float(tap_interval) / 100 tap_point = Point2D((int)(distance * r + sling.X), target.Y) return self.get_time_by_distance(sling, release, tap_point)
def set_trajectory(self, sling, release_point): """ Choose a trajectory by specifying the sling location and release point * Derive all related parameters (angle, velocity, equation of the parabola, etc) * * @param sling - bounding rectangle of the slingshot * release_point - point where the mouse click was released from * """ # don't update parameters if the ref point and release point are the same if self._traj_set and self._ref != None and self._ref == self.get_reference_point(sling) and \ self._release != None and self._release == release_point: return # set the scene parameters self._scale = sling.height + sling.width self._ref = self.get_reference_point(sling) # set parameters for the trajectory self._release = Point2D(release_point.X, release_point.Y) # find the launch angle self._theta = atan2(self._release.Y - self._ref.Y, self._ref.X - self._release.X) # work out initial velocities and coefficients of the parabola self._ux = self._velocity * cos(self._theta) self._uy = self._velocity * sin(self._theta) self._a = -0.5 / (self._ux * self._ux) self._b = self._uy / self._ux # work out points of the trajectory for x in range(0, self.X_MAX): xn = x / self._scale y = self._ref.Y - (int)( (self._a * xn * xn + self._b * xn) * self._scale) self._trajectory.append(Point2D(x + self._ref.X, y)) # turn on the setTraj flag self._traj_set = True
def find_release_point_partial_power(self, sling, theta, v_portion): """find the release point given the sling location, launch angle and velocity * * @param sling - bounding rectangle of the slingshot * theta - launch angle in radians (anticlockwise from positive direction of the x-axis) * v_portion - exit velocity as a proportion of the maximum velocity (maximum self.STRETCH) * @return the release point on screen * """ mag = self.get_scene_scale(sling) * self.STRETCH * v_portion ref = self.get_reference_point(sling) release = Point2D((int)(ref.X - mag * cos(theta)), (int)(ref.Y + mag * sin(theta))) return release
def find_release_point(self, sling, theta): """find the release point given the sling location and launch angle, using maximum velocity * * @param sling - bounding rectangle of the slingshot * theta - launch angle in radians (anticlockwise from positive direction of the x-axis) * @return the release point on screen * """ mag = sling.height * 5 print('mag ', mag) ref = self.get_reference_point(sling) print('ref ', ref) print('cos theta ', cos(theta)) # print('sin theta ',sin(theta)) release = Point2D(int(ref.X - mag * cos(theta)), int(ref.Y + mag * sin(theta))) return release
def get_reference_point(self, sling): """find the reference point given the sling""" p = Point2D(int(sling.X + self.X_OFFSET * sling.width), int(sling.Y + self.Y_OFFSET * sling.width)) return p
"""finds the active bird, i.e., the one in the slingshot""" # assumes that the active bird is the bird at the highest position activeBird = None for r in birds: if activeBird == None or activeBird.Y > r.Y: activeBird = r return activeBird def get_tap_time(self, sling, release, target, tap_interval): """finds the active bird, i.e., the one in the slingshot""" if tap_interval == 0: return 0 distance = target.X - sling.X r = float(tap_interval) / 100 tap_point = Point2D((int)(distance * r + sling.X), target.Y) return self.get_time_by_distance(sling, release, tap_point) # test if __name__ == "__main__": tp = SimpleTrajectoryPlanner() ys = [200, 250] xs = [40, 60] sling = Rectangle([ys, xs]) target = Point2D(300, 100) traj_pts = tp.estimate_launch_point(sling, target) for pt in traj_pts: print(pt)
def solve(self, angle): """ * Solve a particular level by shooting birds directly to pigs * @return GameState: the game state after shots. """ ground_truth_type = 'groundTruth' vision = self._updateReader(ground_truth_type) if not vision.is_vaild(): return self.ar.get_game_state() if self.showGroundTruth: vision.showResult() sling = vision.find_slingshot_mbr()[0] # TODO: look into the width and height issue of Traj planner sling.width, sling.height = sling.height, sling.width # get all the pigs pigs = vision.find_pigs_mbr() print("no of pigs: " + str(len(vision.find_pigs_mbr()))) for pig in pigs: print("pig location: " + str(pig.get_centre_point())) state = self.ar.get_game_state() # if there is a sling, then play, otherwise skip. if sling != None: # If there are pigs, we pick up a pig randomly and shoot it. if pigs: release_point = None # random pick up a pig pig = pigs[random.randint(0, len(pigs) - 1)] temp_pt = pig.get_centre_point() # TODO change computer_vision.cv_utils.Rectangle # to be more intuitive _tpt = Point2D(temp_pt[1], temp_pt[0]) # if the target is very close to before, randomly choose a # point near it if self.prev_target != None and self.prev_target.distance( _tpt) < 10: _angle = random.uniform(0, 1) * pi * 2 _tpt.X = _tpt.X + int(cos(_angle)) * 10 _tpt.Y = _tpt.Y + int(sin(_angle)) * 10 print("Randomly changing to ", _tpt) self.prev_target = Point2D(_tpt.X, _tpt.Y) ################estimate the trajectory################### print( '################estimate the trajectory###################' ) pts = self.tp.estimate_launch_point(sling, _tpt) pts = [] if not pts: # Add logic to deal with unreachable target print( "the target is not reachable directly with the birds") print("no trajectory can be provided") print("just shoot...") release_point = Point2D(-100, angle) elif len(pts) == 1: release_point = pts[0] elif len(pts) == 2: # System.out.println("first shot " + first_shot) # randomly choose between the trajectories, with a 1 in # 6 chance of choosing the high one if random.randint(0, 5) == 0: release_point = pts[1] else: release_point = pts[0] ref_point = self.tp.get_reference_point(sling) # Get the release point from the trajectory prediction module tap_time = 0 if release_point != None: release_angle = self.tp.get_release_angle( sling, release_point) print("Release Point: ", release_point) print("Release Angle: ", degrees(release_angle)) tap_interval = 0 birds = vision.find_birds() bird_on_sling = vision.find_bird_on_sling(birds, sling) bird_type = bird_on_sling.type print("bird_type ", bird_type) if bird_type == GameObjectType.REDBIRD: tap_interval = 0 # start of trajectory elif bird_type == GameObjectType.YELLOWBIRD: tap_interval = 65 + random.randint( 0, 24) # 65-90% of the way elif bird_type == GameObjectType.WHITEBIRD: tap_interval = 50 + random.randint( 0, 19) # 50-70% of the way elif bird_type == GameObjectType.BLACKBIRD: tap_interval = 0 # do not tap black bird elif bird_type == GameObjectType.BLUEBIRD: tap_interval = 65 + random.randint( 0, 19) # 65-85% of the way else: print("should not happen") tap_interval = 60 tap_time = self.tp.get_tap_time(sling, release_point, _tpt, tap_interval) else: print("No Release Point Found") return self.ar.get_game_state() # check whether the slingshot is changed. the change of the slingshot indicates a change in the scale. self.ar.fully_zoom_out() vision = self._updateReader(ground_truth_type) if isinstance(vision, GameState): return vision if self.showGroundTruth: vision.showResult() _sling = vision.find_slingshot_mbr()[0] _sling.width, _sling.height = _sling.height, _sling.width if _sling != None: scale_diff = (sling.width - _sling.width)**2 + ( sling.height - _sling.height)**2 if scale_diff < 25: dx = int(release_point.X - ref_point.X) dy = int(release_point.Y - ref_point.Y) if dx < 0: print('ref point ', ref_point.X, ',', ref_point.Y) self.ar.shoot(ref_point.X, ref_point.Y, dx, dy, 0, tap_time, False) state = self.ar.get_game_state() if state == GameState.PLAYING: vision = self._updateReader(ground_truth_type) if isinstance(vision, GameState): return vision if self.showGroundTruth: vision.showResult() else: print( "Scale is changed, can not execute the shot, will re-segement the image" ) else: print( "no sling detected, can not execute the shot, will re-segement the image" ) return state