示例#1
0
    def pose_control(self, robot):

        robot.goal = self.look_ahead(robot)

        # distance to goal
        distance = utils.euclidean_distance(robot.states, robot.goal)

        # PID controller for velocity
        velocity_control = self.gains[0] * distance
        # angle control
        angle_to_point = (
            utils.angle_between_points(robot.states, robot.goal) -
            robot.states[2][0] + math.pi) % (2 * math.pi) - math.pi
        beta = (robot.goal[2] - robot.states[2][0] - angle_to_point +
                math.pi) % (2 * math.pi) - math.pi

        # derivative term for angle control
        error_diff = angle_to_point - self.error_old
        self.error_old = angle_to_point

        # maneuver
        if angle_to_point > math.pi / 2 or angle_to_point < -math.pi / 2:
            velocity_control = -velocity_control

        return np.array([
            velocity_control, self.gains[2] * angle_to_point +
            self.gains[3] * beta + self.gains[1] * error_diff
        ])
示例#2
0
    def compute_solution(self):
        self.solution = []
        for index, node in self.data.items():
            if index == 1:
                continue
            best_neuron = None
            best_distance = None
            for count, neuron in enumerate(self.neurons):
                if not neuron[2]:
                    continue
                distance = euclidean_distance(node, neuron)
                if not best_neuron or distance < best_distance:
                    best_distance = distance
                    best_neuron = count
            self.solution.append((index, best_neuron))

        # add depots between nodes
        for count, depot in enumerate(self.neurons):
            if depot[2]:
                continue
            self.solution.append((1, count))

        # sort solution according to neuron index
        self.solution.sort(key=lambda x: x[1])

        # split solution in salesmen
        temp_solution = []
        last_index = 0
        for index, node in enumerate(self.solution):
            if node[0] == 1:
                temp_solution.append(
                    [item[0] for item in self.solution[last_index:index]])
                last_index = index + 1
        self.solution = temp_solution
示例#3
0
 def look_ahead(self, robot):
     """
     search for the closest point on the reference path to the robot and return 
     a look ahed point (a point a little further than the closest one)
     """
     min_dist = float('inf')
     dist = 0.0
     idx = 0
     goal = [0.0, 0.0, 0.0]
     for i in range(len(robot.path[0]) -
                    robot.lookahead_idx):  # find closest path point
         dist = utils.euclidean_distance(
             (robot.path[0][i], robot.path[1][i]), robot.states)
         if dist < min_dist:
             min_dist = dist
             idx = i
             goal[0] = robot.path[0][i + robot.lookahead_idx]
             goal[1] = robot.path[1][i + robot.lookahead_idx]
             goal[2] = math.atan2(robot.path[1][i + 1] - robot.path[1][i],
                                  robot.path[0][i + 1] - robot.path[0][i])
             if len(
                     robot.path[0]
             ) < robot.lookahead_idx + 1:  # if close to final goal, returns final goal
                 goal[0] = robot.path[0][-1]
                 goal[1] = robot.path[1][-1]
                 goal[2] = math.atan2(
                     robot.path[1][i + 1] - robot.path[1][i],
                     robot.path[0][i + 1] - robot.path[0][i])
     for i in range(idx):  # delete passed path points
         robot.path = np.delete(robot.path, [i], 1)
     return goal
示例#4
0
 def get_distance(self, x, y):
     if x > y:
         x, y = y, x
     if (x, y) in self.distance_cache:
         return self.distance_cache[(x, y)]
     distance = euclidean_distance(self.data[x], self.data[y])
     self.distance_cache[(x, y)] = distance
     return distance
示例#5
0
def merge_duplicate_nodes(nodes, edges, distance_threshold=DISTANCE_THRESHOLD):
    r"""
    Merge duplicate nodes and modify edges accordingly. Nodes are considered coincident if closer than a threshold
    
    :param nodes: list of nodes (x, y)
    :param edges: list of edges (node_a_id, node_b_id, road_id)
    :param distance_threshold: maximum distance for points to be considered coincident.
    :return nodes: list of nodes (x, y) after cleaning
    :return edges: list of edges (node_a_id, node_b_id, road_id) after cleaning
    :return len(to_del): how many nodes have been deleted in the merging procedure
    """
    to_del = set()  # nodes to be deleted (duplicates)
    to_del_edges = []  # edges to be deleted (duplicates)
    replace_destination = dict()  # to which node a duplicate will be substituted. used to handle recurrent dependencies
    for i, (ax, ay) in enumerate(nodes):
        for j in range(i + 1, len(nodes)):
            bx, by = nodes[j]
            if euclidean_distance(ax, ay, bx, by) < distance_threshold:
                # check if a coincides with b
                replace_destination[j] = i
                for k, edge in enumerate(edges):
                    # update all edges that have the removed duplicate node to point to the substitutive one
                    a, b, id_road = edge
                    a = a if a != j else i
                    b = b if b != j else i
                    edges[k] = [a, b, id_road]
                to_del.add(j)

    to_del = list(to_del)
    old_nodes = nodes[:]  # make a copy of nodes, for the following self-edge removal
    
    # simplify recursive dependencies in the destinations for the replacemente
    for k in replace_destination.keys():
        while replace_destination[k] in replace_destination.keys():
            replace_destination[k] = replace_destination[replace_destination[k]]
    
    # delete duplicate nodes starting from the end of the list to not break indexing in the iteration
    for i in reversed(sorted(to_del)):
        del nodes[i]
        
    # delete self-edges (we found some self-edges from point to itself. This removes this self-edges)
    for i in range(len(edges)):
        a, b, id_road = edges[i]
        a = nodes.index(old_nodes[a]) if a not in replace_destination.keys() else nodes.index(old_nodes[replace_destination[a]])
        b = nodes.index(old_nodes[b]) if b not in replace_destination.keys() else nodes.index(old_nodes[replace_destination[b]])
        if a == b:
            to_del_edges.append(i)
        edges[i] = [a, b, id_road]

    # delete duplicate edges starting from the end of the list to not break indexing in the iteration
    if len(edges) > 1:
        for i in reversed(to_del_edges):
            del edges[i]
    
    return nodes, edges, len(to_del)
示例#6
0
 def steer(self, xrand, closest_node, closest_idx):
     orientation = math.atan2(xrand[1] - closest_node[1],
                              xrand[0] - closest_node[0])
     distance = utils.euclidean_distance(xrand, closest_node)
     new_node = [xrand[0], xrand[1], infinity, None]
     if distance > self.expand_distance:
         new_node[0] = closest_node[0] + self.expand_distance * math.cos(
             orientation)
         new_node[1] = closest_node[1] + self.expand_distance * math.sin(
             orientation)
     return new_node
示例#7
0
 def get_costs(self, new_node, near_nodes_idx):
     cost_list = []
     if near_nodes_idx:
         for idx in near_nodes_idx:
             dx = new_node[0] - self.nodes[idx][0]
             dy = new_node[1] - self.nodes[idx][1]
             d = math.sqrt(dx**2 + dy**2)
             theta = math.atan2(dy, dx)
             distance = utils.euclidean_distance(new_node, self.nodes[idx])
             orientation = math.atan2(new_node[1] - self.nodes[idx][1],
                                      new_node[0] - self.nodes[idx][0])
             if distance != d or orientation != theta:
                 pass
             if self.collision_free(new_node, self.nodes[idx]):
                 cost_list.append(
                     self.nodes[idx][2] +
                     utils.euclidean_distance(new_node, self.nodes[idx]))
             else:
                 cost_list.append(infinity)
     return cost_list
示例#8
0
 def collision_free(self, node, parent):
     #        node_ = [node[0], node[1]]
     parent_ = copy.deepcopy(parent)
     distance = utils.euclidean_distance(parent_, node)
     orientation = math.atan2(node[1] - parent_[1], node[0] - parent_[0])
     line = np.arange(0, distance, 0.1)
     for i in line:
         parent_[0] += self.expand_distance * math.cos(orientation)
         parent_[1] += self.expand_distance * math.sin(orientation)
         if not self.obstacle_free(parent_):
             return False
     return True
示例#9
0
    def rewire_tree(self, near_nodes_idx, new_node):
        cardV = len(self.nodes)

        for idx in near_nodes_idx:
            node = self.nodes[idx]
            distance = utils.euclidean_distance(new_node, node)
            cost = new_node[2] + distance

            if node[2] > cost:
                if self.collision_free(new_node, node):
                    node[2] = cost
                    node[3] = cardV - 1
示例#10
0
def join_intersection(line, point, threshold=STEP/50):
    r"""
    Check if the two newly generated lines from intersection are long enough. Return the one that are long enough.
    We threshold the minimum length of the segment to prevent noise or irrepresentability in the low-resolution
    semantic segmentation.
    
    :param line: input line
    :param point: intersection point
    :param threshold: minimum length for a new line to be accepted
    :return: new accepted lines after intersection
    """
    new_lines = []
    for p in [line.a, line.b]:
        dist = euclidean_distance(p, point)
        if dist > threshold:
            new_lines.append(Line(p, point))
    return new_lines
示例#11
0
    def get_index(self):
        # find closest node to the goal with best cost
        distance2goal = [
            utils.euclidean_distance(node, self.goal) for node in self.nodes
        ]
        indexes = []

        for distance in distance2goal:
            if distance <= 2 * self.expand_distance:
                indexes.append(distance2goal.index(distance))

        if indexes:
            mincost = min([self.nodes[i][2] for i in indexes])
            for idx in indexes:
                if self.nodes[idx][2] == mincost:
                    return idx

        return None
示例#12
0
    def lqr_steer_control(self, robot):
        self.Q = np.eye(robot.states.shape[0])
        self.R = np.eye(2)
        robot.goal = self.look_ahead(robot)

        ######## Linearization ########
        vel = utils.euclidean_distance(robot.states, robot.goal)
        A, B = robot.jacobi()

        ######## DARE ########
        X = self.solve_DARE(A, B)

        ######## LQR solution ########
        lqr_k = self.solve_lqr(X, A, B)

        error = robot.error()

        ustar = -lqr_k @ error
        # calc steering input
        delta = utils.truncate_angle(ustar[1])

        return np.array([vel, delta])
def sorted_cand_ind(eval_df, cand_df, n_eval, n_cand):
    """
        Sort indices of candidate data according to
            their Euclidean distance to each evaluation data in deep feature space.
            Args:
                eval_df (tensor): deep features of evaluation data.
                cand_df (tensor): deep features of evaluation data.
                n_eval (int): number of evaluation data.
                n_cand (int): number of candidate data.
            Returns
                sorted_cand_ind (tensor): sorted indices of candidate set w.r.t. each evaluation data.
    """
    # Sort indices of candidate set according to distance w.r.t. evaluation set in deep feature space
    # Preprocess feature vectors to facilitate vector-wise distance computation
    eval_df_repeat = eval_df.repeat([1, n_cand]).reshape(
        [n_eval * n_cand, eval_df.shape[1]])
    cand_df_tile = cand_df.repeat([n_eval, 1])
    # Compute distance between evaluation and candidate feature vectors
    distance_vector = euclidean_distance(eval_df_repeat, cand_df_tile)
    # Turn distance vector into distance matrix
    distance_matrix = distance_vector.reshape((n_eval, n_cand))
    # Sort candidate set indices based on distance
    sorted_cand_ind_ = distance_matrix.argsort(1)
    return sorted_cand_ind_
示例#14
0
 def get_best_matching_unit(self, node):
     return min(enumerate(filter(lambda k: k[2], self.neurons)),
                key=lambda x: euclidean_distance(x[1], node))
示例#15
0
                                                                  path[1],
                                                                  ds=0.25)
    path = [rx, ry]

    ################ Initialize model and control #################
    robot_ground_truth = extended_bicycle("RK2", states, controls, path, dT)
    robot = extended_bicycle("RK3", states, controls, path, dT)

    control = controllers(robot.gains)

    ekf = Kalman_filter(states.shape[0])
    mc = ManualControl()
    mpc = NonlinearMPC(2.5, dT)

    print("Start Simulation")
    while utils.euclidean_distance(goal, robot.states) > 0.3:

        #        robot.controls = mc.get_controls(anime.fig, robot.states, dT)
        control.lqr_vel_steer_control(robot)
        robot.controls = mpc.MPC(robot.states, robot.path)

        robot_ground_truth.controls = copy.deepcopy(robot.controls)
        #
        add_noise = False
        robot_ground_truth.run(add_noise)  # ground truth
        #        add_noise = True
        robot.run(add_noise)
        #        robot = ekf.run_filter(robot, robot_ground_truth.states)
        #        utils.collision_square_obstacle(robot.states, )
        states_history = np.hstack((states_history, robot.states))
        states_history_ground_truth = np.hstack(