def gbfs(self, problem):
        q = [Path([problem.getInitial()])]
        visited = []
        i = 0
        while q:
            i = i + 1
            currentPath = q.pop(0)
            currentState = currentPath.getLast()

            if currentState == problem.getFinal():
                return currentPath, i

            visited.append(currentState)

            aux = []

            for child in currentState.allNextStates():
                if child not in visited:
                    aux.append(child)

            aux = self.orderStates(aux)

            for state in aux:
                p = Path(deepcopy(currentPath.getValues()))
                p.add(State(deepcopy(state.getValues())))
                q.append(p)

        return None, i
예제 #2
0
class BestFirst:
    """Class representing Best First algorithm
    It returns a path depending on which country has the highest number of cases on the next day"""
    def __init__(self, starting_country, starting_date, alg_graph, goal_function):
        """Initializes BestFirst Algorithm object
        You specify the country and date you start with and a graph to work with"""
        self.path = Path(starting_country, starting_date)
        self.graph = alg_graph
        self.goal_function = goal_function


    def finding_path(self):
        """Main function to find a path according to BestFirst algorithm
            It returns a path object"""
        start_country, start_date = self.path.countries[0], self.path.start_date
        stats = self.graph.get_stats(start_country) # Here is a country which has latest data
        last_date = datetime.date(stats[0, 2], stats[0, 1], stats[0, 0])
        current_country_neighbors = self.graph.get_neighbours(start_country)
        current_country, current_date = start_country, start_date
        while current_date != last_date:
            current_country = self.choose_neighbor_with_max_cases(current_country_neighbors)
            current_country_neighbors = self.graph.get_neighbours(current_country)
            current_date += datetime.timedelta(days=1)
            self.path.add(current_country)
        self.path.eval(self.graph, self.goal_function)

    def choose_neighbor_with_max_cases(self, countries_list=None):
        """Function which chooses the best country to go to next
        It looks for the biggest number of cases from countries list"""
        countries_list = countries_list if countries_list else []
        try:
            if not countries_list:
                raise Exception
        except Exception as e:
            print("There are no neighbors to choose from: {0}".format(e))
        max_cases = -1
        country_with_max_cases = ''
        for country in countries_list:
            if self.path.get_profit(self.graph, country, self.goal_function) > max_cases:
                max_cases = self.path.get_profit(self.graph, country, self.goal_function)
                country_with_max_cases = country
        return country_with_max_cases

    def work(self):
        """Method which initializes every method essential to find a path"""
        self.finding_path()
예제 #3
0
 def initialize_frontier(self):
     path = Path()
     path.add(self.start)
     heapq.heappush(self.frontier, path)
     return self.frontier
예제 #4
0
class CarFree2D:
    def __init__(self, id: int, spawn_x, spawn_y, start, start_dir, end_dir,
                 size_x, size_y, angle, max_vel, max_acc, color, min_latency,
                 max_latency, errorrate):
        self.ghost = False
        # PHYSICAL PROPERTIES
        self.color = color  # color code
        self.id = id  # unique car id
        self.spawn = [spawn_x, spawn_y]  # spawnpoint
        self.destination = 0
        self.position_x = [spawn_x]  # not used for EventQueue
        self.position_y = [spawn_y]
        self.direction = start_dir  # direction of the car
        self.start_direction = angle  # start-direction of the car
        self.last_position = [spawn_x,
                              spawn_y]  # position after last control input
        self.length = size_x  # in m
        self.width = size_y  # in m
        self.start_dir = start_dir
        self.end_dir = end_dir
        self.end = None
        self.min_latency = min_latency
        self.max_latency = max_latency
        self.errorrate = errorrate
        self.start_time = start
        self.wheelbase = self.length - 0.5 * self.width
        # VELOCITY
        self.last_velocity = 0
        self.last_velocity_x = 0  # velocity after last control input
        self.last_velocity_y = 0
        self.velocity = []  # not used for EventQueue
        self.max_velocity = max_vel  # absolute limit of velocity
        # ACCELERATION
        self.acceleration = 0  # acceleration given by last control input
        self.acceleration_y = 0
        self.acceleration_x = 0
        self.max_acceleration = max_acc  # absolute limit of acceleration
        self.acceleration_x_c = 0
        self.acceleration_y_c = 0
        self.acceleration_controller = 0
        # STEERING
        self.steering = 0  # steering angle given by last control input
        self.direction = 0  # direction angle given by last control input
        self.steering_control = 0
        # PATH
        self.shape = []  # shape of the planned path (without exact timestamp)
        self.path = Path(self.spawn)  # "shape" with exact timestamp
        self.waypoints = []  # list for the given points with the
        self.planner = None
        # CONTROLS
        self.time_last_control = start - lib.dt  # timestamp of last control input
        self.time_last_update = start - lib.dt  # timestamp of last given acceleration
        self.time_last_step = start - lib.dt
        self.stop = False  # False: car drives, True: car stops (or will stop within the next time (t < ts)
        self.stop_time = 0  # timestamp of stop (velocitiy 0 reached)
        self.controller = Controller(self, lib.k_p, lib.k_d)
        # DEBUGGING
        self.debugging1 = []
        self.debugging2 = []
        self.debugging3 = []
        self.debugging4 = []
        self.dc_pos = []
        dim = len(lib.statespace.A)
        self.old_state = [
            np.zeros(dim).reshape(-1, 1),
            np.zeros(dim).reshape(-1, 1)
        ]
        self.state = [np.zeros(dim), np.zeros(dim)]
        self.full_arc = 0
        self.counter = 0
        self.min_dist = self.make_min_dist()
        self.distances = []

    # GETTER
    # currenttly not used
    def get_speed(
        self, absolute
    ):  # absolute is boolean - true returns absolute value, false vectorial speed
        if absolute:
            return sqrt(self.velocity[0] * self.velocity[0] +
                        self.velocity[1] * self.velocity[1])
        else:
            return self.velocity

    # currenttly not used
    def get_acceleration(self):
        return self.acceleration

    def set_first_position(self):
        self.position_x = [self.spawn[0]]
        self.position_y = [self.spawn[1]]
        self.last_position = self.spawn

        # sets waypoint (given by *.json file) for the car
    def set_waypoint(self, x, y):
        p = Point(x, y)
        self.path.add(p)
        self.waypoints.append(p)
        # raise Exception('The point (' + str(p.x) + '|' + str(p.y) + ') is too far away. Skipped.')

    def make_min_dist(self):
        edges = [
            [self.spawn[0] - self.length / 2, self.spawn[1] - self.width / 2],
            [self.spawn[0] + self.length / 2, self.spawn[1] - self.width / 2],
            [self.spawn[0] + self.length / 2, self.spawn[1] + self.width / 2],
            [self.spawn[0] - self.length / 2, self.spawn[1] + self.width / 2]
        ]
        out = lib.dist(self.spawn, edges[0])
        for e in edges:
            dist = lib.dist(self.spawn, e)
            if dist > out:
                out = dist
        return out

    # creates spline for the given waypoints (from the *.json file)
    def create_spline(self):
        self.planner = PathPlanner(self, self.max_velocity,
                                   self.max_acceleration)
        self.planner.make_path(self.path.points)
        self.write_path()
        if not self.ghost:
            pass
            #self.make_controls()
            self.make_controls()

        self.planner.t_equi_in_t = (np.array(self.planner.t_equi_in_t) +
                                    self.start_time).tolist()
        self.stop_time = self.planner.t_equi_in_t[-1]

    def write_path(self):
        for point in self.planner.path_from_v_equi_in_t:
            self.shape.append([np.real(point), np.imag(point)])
        pass

    def test_dc_motor(self, ax, ay):

        self.acceleration_x = ax
        self.acceleration_y = ay
        self.counter += 1
        # x direction:
        self.state[0] = lib.statespace.A.A.dot(
            self.old_state[0]) + lib.statespace.B.A.dot(ax)
        x = lib.statespace.C.A.dot(
            self.old_state[0]) + lib.statespace.D.A.dot(ax)
        # y direction:
        self.state[1] = lib.statespace.A.A.dot(
            self.old_state[1]) + lib.statespace.B.A.dot(ay)
        y = lib.statespace.C.A.dot(
            self.old_state[1]) + lib.statespace.D.A.dot(ay)

        self.old_state = self.state
        return x[0][0], y[0][0]

    def steer(self, t, ax, ay, stop):
        t = round(t, 5)
        ax -= self.acceleration_x_c
        ay -= self.acceleration_y_c
        self.acceleration_x = ax
        self.acceleration_y = ay
        lp = self.last_position[:]

        # x direction
        self.state[0] = lib.statespace.A.A.dot(
            self.old_state[0]) + lib.statespace.B.A.dot(ax)
        x = lib.statespace.C.A.dot(
            self.old_state[0]) + lib.statespace.D.A.dot(ax)
        x = x[0][0]
        # y direction:
        self.state[1] = lib.statespace.A.A.dot(
            self.old_state[1]) + lib.statespace.B.A.dot(ay)
        y = lib.statespace.C.A.dot(
            self.old_state[1]) + lib.statespace.D.A.dot(ay)
        y = y[0][0]
        self.position_x.append(self.spawn[0] + x)
        self.position_y.append(self.spawn[1] + y)
        self.last_position = [self.spawn[0] + x, self.spawn[1] + y]

        self.old_state = self.state

        if stop:
            self.stop_time = t
        else:
            comp_vel = complex(self.last_velocity_x, self.last_velocity_y)
            self.direction = np.angle([comp_vel])[0]
        self.stop = stop
        try:
            self.direction = lib.angle(
                Point(self.position_x[-2], self.position_y[-2]),
                Point(self.position_x[-1], self.position_y[-1]))
        except IndexError:
            pass

        self.time_last_step = t

    def control(self, t, ax, ay):
        self.acceleration_x_c = ax
        self.acceleration_y_c = ay

    # CONVERTING CONTROL_PREP INTO CONTROLS FOR CAR
    # [timestamp, estimated x, estimated y, abs(acceleration), direction to drive]
    def make_controls(self):
        stop_time = self.planner.t_equi_in_t[-1]
        stop = False
        t = self.start_time
        for acc in self.planner.acceleration_from_v_equi_in_t:
            if acc == self.planner.acceleration_from_v_equi_in_t[-1]:
                stop = True
            ev = Event(t, self,
                       (t, self, np.real(acc), np.imag(acc), stop, "steering"),
                       lambda: lib.eventqueue.car_steering)
            lib.eventqueue.add_event(ev)
            t += lib.pt
        # fills the self.controls list with acceleration values
        self.controller.set_path(self.planner.path_from_v_equi_in_t)

    # used with EventQueue
    # returns position of the car at specific time t
    # also more information available (but certainly not needed),f.e. acceleration, direction, steering, angle, ...
    def get_data(self, t):
        if self.ghost:
            try:
                if (t - self.start_time) > 0:
                    index = int((t - self.start_time) / lib.pt)
                else:
                    index = 0
                point = self.planner.path_from_v_equi_in_t[index]
                vel = self.planner.velocity_from_v_equi_in_t[index]
                dir = np.angle([vel])
            except IndexError:
                point = self.planner.path_from_v_equi_in_t[-1]
                vel = self.planner.velocity_from_v_equi_in_t[-1]
                vel_dir = self.planner.velocity_from_v_equi_in_t[-2]
                dir = np.angle([vel_dir])

            vel = abs(vel)
            x = point.real
            y = point.imag

        else:
            if not self.stop:
                dt = (t - self.time_last_control)

            else:
                dt = (self.stop_time - self.time_last_control)

            x = self.last_position[0]
            y = self.last_position[1]

            dir = round(self.direction, 5)

            vel = self.last_velocity

        if t == 0:
            dir = self.start_direction
        return [t, self.id, round(x, 4), round(y, 4), vel, dir]
예제 #5
0
 def initialize_frontier(self):
     path = Path()
     path.add(self.start)
     self.frontier.insert(0, path)
     return self.frontier
예제 #6
0
class CarAckermann:
    def __init__(self, id: int, spawn_x, spawn_y, start, start_dir, end_dir,
                 size_x, size_y, angle, max_vel, max_acc, max_steering_angle,
                 color, min_latency, max_latency, errorrate, seg_len,
                 channel_properties):
        self.ghost = False
        # PHYSICAL PROPERTIES
        self.color = color  # color code
        self.id = id  # unique car id
        self.spawn = [spawn_x, spawn_y]  # spawnpoint
        self.destination = 0

        self.position_x = [spawn_x]  # not used for EventQueue
        self.position_y = [spawn_y]
        self.direction = start_dir  # direction of the car
        self.start_direction = angle  # start-direction of the car
        self.last_position = [spawn_x,
                              spawn_y]  # position after last control input
        self.length = size_x  # in m
        self.width = size_y  # in m
        self.start_dir = start_dir
        self.end_dir = end_dir
        self.end = None
        self.min_latency = min_latency
        self.max_latency = max_latency
        self.errorrate = errorrate
        self.start_time = start
        self.wheelbase = self.length - 0.5 * self.width
        self.rearbase = 0.5 * self.width
        self.wheelangles = [0, 0]
        self.stored_a = []

        # VELOCITY
        self.last_velocity = 0
        self.velocity = []  # not used for EventQueue
        self.max_velocity = max_vel  # absolute limit of velocity
        # ACCELERATION
        self.acceleration = 0  # acceleration given by last control input
        self.max_acceleration = max_acc  # absolute limit of acceleration
        self.acceleration_controller = 0
        self.acc_debug = []
        self.emergency_brake = False
        # STEERING
        self.steering = 0  # steering angle given by last control input
        self.direction = 0  # direction angle given by last control input
        self.steering_control = 0
        self.max_steering_angle = max_steering_angle
        # PATH
        self.shape = []  # shape of the planned path (without exact timestamp)
        self.path = Path(self.spawn)  # "shape" with exact timestamp
        self.path_buffer = []
        self.segment_length = seg_len  # length of segments (path is divided in segments which are then
        # sent to the AGV
        self.last_segment_time = 0  # start-time of the last received path-segment
        self.waypoints = []  # list for the given points with the
        self.planner = None
        # CONTROLS
        self.time_last_control = start - lib.dt  # timestamp of last control input
        self.time_last_update = start - lib.dt  # timestamp of last given acceleration
        self.time_last_step = start - lib.dt
        self.stop_time = 0  # timestamp of stop (velocity 0 reached)
        self.controller = Controller(self, lib.k_p, lib.k_d)
        dim = len(lib.statespace.A)
        self.old_state = np.zeros(dim).reshape(-1, 1)
        self.state = None
        self.full_arc = 0
        self.min_dist = self.make_min_dist()
        self.distances = []
        self.lat_distances = []
        #CHANNEL
        self.channel = Channel(self.errorrate, channel_properties)
        # DEBUGGING
        self.debugging = []
        self.arc_debug = []

    def set_first_position(self):
        self.position_x = [self.spawn[0]]
        self.position_y = [self.spawn[1]]
        self.last_position = self.spawn

        # sets waypoint (given by *.json file) for the car
    def set_waypoint(self, x, y):
        p = Point(x, y)
        self.path.add(p)
        self.waypoints.append(p)
        # raise Exception('The point (' + str(p.x) + '|' + str(p.y) + ') is too far away. Skipped.')

    # used for collision control
    def make_min_dist(self):
        edges = [
            [self.spawn[0] - self.length / 2, self.spawn[1] - self.width / 2],
            [self.spawn[0] + self.length / 2, self.spawn[1] - self.width / 2],
            [self.spawn[0] + self.length / 2, self.spawn[1] + self.width / 2],
            [self.spawn[0] - self.length / 2, self.spawn[1] + self.width / 2]
        ]
        out = lib.dist(self.spawn, edges[0])
        for e in edges:
            dist = lib.dist(self.spawn, e)
            if dist > out:
                out = dist
        return out

    # creates spline for the given waypoints (from the *.json file)
    def create_spline(self):
        self.planner = PathPlanner(self, self.max_velocity,
                                   self.max_acceleration)
        self.planner.make_path(self.path.points)
        self.stop_time = self.planner.t_equi_in_t[-1]
        self.write_path()
        self.planner.t_equi_in_t = (np.array(self.planner.t_equi_in_t) +
                                    self.start_time).tolist()
        self.update_path()

    def write_path(self):
        for point in self.planner.path_from_v_equi_in_t:
            self.shape.append([np.real(point), np.imag(point)])

    def steer(self, t, a, angle):
        if self.emergency_brake:
            a = -self.max_acceleration  # braking as fast as possible
        else:
            a += self.acceleration_controller  # controlling the current acceleration
        self.acc_debug.append(a)
        angle = (angle + self.steering_control)
        self.debugging.append(angle)
        # angle = min(self.max_steering_angle, angle)
        # angle = max(-self.max_steering_angle, angle)
        if (self.last_velocity <= 0) & self.emergency_brake:
            self.stop_time = t

        if t < self.stop_time:
            start_angle = self.direction - np.pi / 2
            pos = np.array(self.last_position) - np.array(
                [0, 0.5 * cos(self.direction) * self.wheelbase])

            # DC-Motor
            self.state = lib.statespace.A.dot(
                self.old_state) + lib.statespace.B.dot(a)
            new_arc = (lib.statespace.C.dot(self.old_state) +
                       lib.statespace.D.dot(a))[0, 0]

            # State Transition
            self.old_state = self.state

            # Saving attributes
            arc = new_arc - self.full_arc
            self.full_arc = new_arc
            self.last_velocity = arc / lib.pt
            self.velocity.append(self.last_velocity)
            self.arc_debug.append(arc)

            try:
                radius = self.wheelbase / tan(angle)
                self.wheelangles = [
                    atan2(self.wheelbase, radius - 0.5 * self.rearbase),
                    atan2(self.wheelbase, radius + 0.5 * self.rearbase)
                ]
                phi = arc / radius
                center_of_turning_cycle = np.array(pos) - np.array([radius, 0])
                point = np.array([radius * cos(phi), radius * sin(phi)])

                point = point + center_of_turning_cycle - pos

                point = np.dot(
                    np.array([[np.cos(start_angle), -np.sin(start_angle)],
                              [np.sin(start_angle),
                               np.cos(start_angle)]]), point.reshape(-1, 1))
                point = point + np.array(pos).reshape(-1, 1)
                self.direction = (phi + self.direction) % (2 * pi)
                self.last_position = (
                    point.reshape(1, -1) +
                    np.array([0, 0.5 * cos(self.direction) * self.wheelbase
                              ])).tolist()[0]

                x = self.last_position[0]
                y = self.last_position[1]
                self.position_x.append(x)
                self.position_y.append(y)

            # in case of a straight movement:
            except ZeroDivisionError:
                x = self.last_position[0] + arc * cos(self.direction)
                y = self.last_position[1] + arc * sin(self.direction)
                self.last_position = [x, y]
                self.position_x.append(x)
                self.position_y.append(y)
                self.wheelangles = [0, 0]

    def control(self, acc):
        self.acceleration_controller = acc

    def make_controls(self):
        t = self.last_segment_time

        for i in range(len(self.stored_a)):
            acc = self.stored_a[i]
            prio = 1  # didsdsdsdfs
            ev = Event(t, self, (round(t, 7), self, acc, "steering"),
                       lambda: lib.eventqueue.car_steering_ackermann, prio)
            lib.eventqueue.add_event(ev)
            t += lib.pt

    # used with EventQueue
    # returns position of the car at specific time t
    # also more information available (but certainly not needed),f.e. acceleration, direction, steering, angle, ...
    def get_data(self, t):
        if self.ghost:
            try:
                if (t - self.start_time) > 0:
                    index = round((t - self.start_time) / lib.pt)
                else:
                    index = 0
                point = self.planner.path_from_v_equi_in_t[index]
                vel = self.planner.velocity_from_v_equi_in_t[index]
                dir = np.angle([vel])

            except IndexError:
                point = self.planner.path_from_v_equi_in_t[-1]
                vel = self.planner.velocity_from_v_equi_in_t[-1]
                vel_dir = self.planner.velocity_from_v_equi_in_t[-2]
                dir = np.angle([vel_dir])
            wheel_angles = [0, 0]
            vel = abs(vel)
            x = point.real
            y = point.imag

        else:
            x = self.last_position[0]
            y = self.last_position[1]

            x = self.position_x[-1]
            y = self.position_y[-1]

            dir = round(self.direction, 5)

            vel = self.last_velocity

            wheel_angles = self.wheelangles

        if t == 0:
            dir = self.start_direction
        return [t, self.id, round(x, 7), round(y, 7), vel, wheel_angles, dir]

    def update_path(self):
        print('update', self.last_segment_time)
        self.stored_a = self.planner.a_from_v_equi_in_t[round(
            self.last_segment_time /
            lib.pt):round((self.last_segment_time + self.segment_length) /
                          lib.pt)]
        # fills the self.controls list with acceleration values
        self.controller.set_path(self.planner.path_from_v_equi_in_t)
        self.make_controls()
        t = self.last_segment_time
        self.last_segment_time += self.segment_length

        if self.last_segment_time < self.stop_time:
            ev = Event(self.last_segment_time - self.segment_length / 3, self,
                       (
                           t,
                           self,
                       ), lambda: lib.eventqueue.update_path)
            lib.eventqueue.add_event(ev)

    def brake(self, t):
        for e in lib.eventqueue.events:
            if e.object == self:
                del e
        self.emergency_brake = True
예제 #7
0
class BruteAlgorithm:
    """Class representing Brute Algorithm
    It takes every possible path in the graph and finds the one,
    on which the doctor cures the highest number of people"""
    def __init__(self, starting_country, starting_date, alg_graph, goal_function):
        """Method which initializes BruteAlgorithm object
            It takes start country and date plus the graph on which it should work on"""
        self.path = Path(starting_country, starting_date)
        self.graph = alg_graph
        self.possible_paths = [tuple([starting_country])]
        stats = self.graph.get_stats(starting_country)  # Here is a country which has latest data
        self.last_date = datetime.date(stats[0, 2], stats[0, 1], stats[0, 0])
        self.days_difference = int((self.last_date - starting_date).days)
        self.goal_function = goal_function

    def generate_paths(self):
        """Method which generates all available paths"""
        for path_list in self.possible_paths:
            if int(self.days_difference) < len(path_list):
                break
            for neighbor in self.graph.get_neighbours(path_list[len(path_list)-1]):
                new_path = list(path_list)
                new_path.append(neighbor)
                self.possible_paths.append(tuple(new_path))

    def choose_best_path(self):
        """Method chooses the best possible path (which has the highest number of cured poeple)"""
        longest_paths = [path for path in self.possible_paths if len(path) == self.days_difference + 1]
        best_path = []
        if self.goal_function == 'recovered':
            best_score = -1
        elif self.goal_function == 'deaths':
            best_score = 1000000000
        for path in longest_paths:
            self.clear_path()
            self.add_whole_path(path)
            self.path.eval(self.graph, self.goal_function)
            if self.goal_function == 'recovered' and self.path.score > best_score:
                best_score = self.path.score
                best_path = path
            elif self.goal_function == 'deaths' and self.path.score < best_score:
                best_score = self.path.score
                best_path = path
        self.clear_path()
        self.add_whole_path(best_path)
        self.path.eval(self.graph, self.goal_function)

    def clear_path(self):
        """Method clears the variable self.path leaving only the starting country"""
        for i in range(len(self.path.countries)-1):
            self.path.countries.pop()
        self.path.score = 0

    def add_whole_path(self, path):
        """Method adds countries which are in the argument 'path'
        (execpt the first one which is already in the variable self.path"""
        for country_index in range(len(path)):
            if country_index == 0:
                continue
            self.path.add(path[country_index])

    def work(self):
        """Method which initializes every method essential to find a path"""
        self.generate_paths()
        self.choose_best_path()