def vision_for(self, agent): """ Строит видение мира для каждого агента :param agent: машинка, из которой мы смотрим :return: список из модуля скорости машинки, направленного угла между направлением машинки и направлением на центр и `agent.rays` до ближайших стен трека (запустите картинку, и станет совсем понятно) """ state = self.agent_states[agent] vision = [ abs(state.velocity), np.sin(angle(-state.position, state.heading)) ] extras = len(vision) delta = pi / (agent.rays - 1) start = rotate(state.heading, -pi / 2) sectors = len(self.map) for i in range(agent.rays): # define ray direction ray = rotate(start, i * delta) # define ray's intersections with walls vision.append(np.infty) for j in range(sectors): inner_wall = self.map[j - 1][0], self.map[j][0] outer_wall = self.map[j - 1][1], self.map[j][1] intersect = intersect_ray_with_segment((state.position, ray), inner_wall) intersect = abs( intersect - state.position) if intersect is not None else np.infty if intersect < vision[-1]: vision[-1] = intersect intersect = intersect_ray_with_segment((state.position, ray), outer_wall) intersect = abs( intersect - state.position) if intersect is not None else np.infty if intersect < vision[-1]: vision[-1] = intersect for obstacle in self.obs: for j in range(len(obstacle)): obstacle_wall = obstacle[j - 1], obstacle[j] intersect = intersect_ray_with_segment( (state.position, ray), obstacle_wall) intersect = abs( intersect - state.position) if intersect is not None else np.infty if intersect < vision[-1]: vision[-1] = intersect assert vision[-1] < np.infty, \ "Something went wrong: {}, {}".format(str(state), str(agent.chosen_actions_history[-1])) assert len(vision) == agent.rays + extras, \ "Something went wrong: {}, {}".format(str(state), str(agent.chosen_actions_history[-1])) return vision
def vision_for(self, agent): """ Строит видение мира для каждого агента :param agent: машинка, из которой мы смотрим :return: список из модуля скорости машинки, направленного угла между направлением машинки и направлением на центр и `agent.rays` до ближайших стен трека (запустите картинку, и станет совсем понятно) """ state = self.agent_states[agent] vision = [abs(state.velocity), np.sin(angle(-state.position, state.heading))] extras = len(vision) delta = pi / (agent.rays - 1) start = rotate(state.heading, - pi / 2) sectors = len(self.map) for i in range(agent.rays): # define ray direction ray = rotate(start, i * delta) # define ray's intersections with walls vision.append(np.infty) for j in range(sectors): inner_wall = self.map[j - 1][0], self.map[j][0] outer_wall = self.map[j - 1][1], self.map[j][1] intersect = intersect_ray_with_segment((state.position, ray), inner_wall) intersect = abs(intersect - state.position) if intersect is not None else np.infty if intersect < vision[-1]: vision[-1] = intersect intersect = intersect_ray_with_segment((state.position, ray), outer_wall) intersect = abs(intersect - state.position) if intersect is not None else np.infty if intersect < vision[-1]: vision[-1] = intersect for obstacle in self.obs: for j in range(len(obstacle)): obstacle_wall = obstacle[j - 1], obstacle[j] intersect = intersect_ray_with_segment((state.position, ray), obstacle_wall) intersect = abs(intersect - state.position) if intersect is not None else np.infty if intersect < vision[-1]: vision[-1] = intersect assert vision[-1] < np.infty, \ "Something went wrong: {}, {}".format(str(state), str(agent.chosen_actions_history[-1])) assert len(vision) == agent.rays + extras, \ "Something went wrong: {}, {}".format(str(state), str(agent.chosen_actions_history[-1])) return vision
def move(self, car_state, action, *args, **kwargs): """ Moves object to the next point according to object's state. If object crosses the wall, move is rejected and object's position remains unchanged. :param car_state: state of car, of class CarState :param action: car action, of class Action :return: tuple(CarState with object's next position, boolean indication whether the collision happened) """ position = car_state.position velocity = car_state.velocity acceleration = rotate(car_state.heading, action.steering * pi / 2) * action.acceleration new_position = position + velocity * self.timedelta + acceleration * ( self.timedelta**2) / 2 collision = self.is_out_of_map(new_position) if collision: return CarState(position, -0.5 * velocity, -car_state.heading), collision else: new_velocity = velocity + acceleration * self.timedelta heading = new_position - position if abs(heading) > 1e-5: heading /= abs(heading) else: heading = car_state.heading return CarState(new_position, new_velocity, heading), collision
def move(self, car_state, action, *args, **kwargs): """ Moves object to the next point according to object's state. If object crosses the wall, move is rejected and object's position remains unchanged. :param car_state: state of car, of class CarState :param action: car action, of class Action :return: tuple(CarState with object's next position, boolean indication whether the collision happened) """ position = car_state.position velocity = car_state.velocity acceleration = rotate(car_state.heading, action.steering * pi / 2) * action.acceleration new_position = position + velocity * self.timedelta + acceleration * (self.timedelta ** 2) / 2 collision = self.is_out_of_map(new_position) if collision: return CarState(position, -0.5 * velocity, -car_state.heading), collision else: new_velocity = velocity + acceleration * self.timedelta heading = new_position - position if abs(heading) > 1e-5: heading /= abs(heading) else: heading = car_state.heading return CarState(new_position, new_velocity, heading), collision