예제 #1
0
def open_spline_chain_main():
    #x = [0, 3, -20, -10]
    #y = [0, 30, -5, -3]
    #th = [np.pi/2., np.pi, -np.pi/2., 0.]
    x = np.cos(np.deg2rad(135.))*np.array([-10., 1., 50.])
    y = np.sin(np.deg2rad(135.))*np.array([-10., 1., 50.])
    th = [np.deg2rad(135.), np.deg2rad(135.), np.deg2rad(135.)]
    X = np.column_stack((x, y))
    # Random desired discretization along the splines for demonstration purposes
    Ns = np.random.random_integers(100., 200., (X.shape[0]-1,))  # one less spline than waypoints.
    sx, sy, sth, length, u, coeffs = PiazziSpline.splineOpenChain(X, th, Ns)

    plt.plot(sx, sy, 'k-', linewidth=2.0)
    #test_x = 3.0
    #test_y = 30.01
    test_x = 0.013
    test_y = 0.008
    u_star, closest, distance = closestPointOnSpline2D(length, sx, sy, test_x, test_y, u, coeffs, guess=None)
    print "closest X = {:.3f}, {:.3f},  u* = {}".format(closest[0], closest[1], u_star)

    # Figure out the LOS controller using this example
    tangent_th = np.interp(u_star, u, sth)
    print "tangent th = {:.3f} deg".format(tangent_th*180.0/np.pi)
    lookAhead = 0.1  # how far forward in u
    lookaheadState = splineToEuclidean2D(coeffs, min(u_star + lookAhead, u[-1]))
    print "lookahead X = {:.3f}, {:.3f}".format(lookaheadState[0], lookaheadState[1])
    dx_global = lookaheadState[0] - closest[0]
    dy_global = lookaheadState[1] - closest[1]
    print "dx_global = {:.3f}, dy_global = {:.3f}".format(dx_global, dy_global)
    dx_frenet = dx_global*math.cos(tangent_th) + dy_global*math.sin(tangent_th)
    dy_frenet = dx_global*math.sin(tangent_th) - dy_global*math.cos(tangent_th)
    print "y error = {:.3f}, dx_frenet = {:.3f}, dy_frenet = {:.3f}".format(distance, dx_frenet, dy_frenet)

    # need sign of distance to spline to change
    # look at sign of cross product to determine "handed-ness"
    angle_from_closest_to_test = math.atan2(closest[1] - test_y, closest[0] - test_x)
    print "angle from closest to test = {:.3f} deg".format(angle_from_closest_to_test*180./np.pi)
    sign_test = np.cross([math.cos(tangent_th), math.sin(tangent_th)], [math.cos(angle_from_closest_to_test), math.sin(angle_from_closest_to_test)])
    distance *= np.sign(sign_test)
    print "distance to spline after sign update = {:.3f}".format(distance)

    # resulting triangle
    relative_angle = math.atan2((distance - dy_frenet), dx_frenet)
    global_angle = tangent_th + relative_angle
    print "relative angle = {:.3f} deg, global angle = {:.3f} deg".format(relative_angle*180./np.pi, global_angle*180./np.pi)

    # plot
    plt.plot(test_x, test_y, 'r+', markersize=12., markeredgewidth=2.0)
    plt.plot(closest[0], closest[1], 'gx', markersize=12., markeredgewidth=2.0)
    plt.plot(lookaheadState[0], lookaheadState[1], 'go', markersize=12., markeredgewidth=2.0)
    result_line = np.array([[test_x, test_y], closest])
    lookAhead_line = np.array([closest, lookaheadState])
    plt.plot(result_line[:, 0], result_line[:, 1], 'b-')
    plt.plot(lookAhead_line[:, 0], lookAhead_line[:, 1], 'g-')
    plt.arrow(closest[0], closest[1], 10.*math.cos(tangent_th), 10.*math.sin(tangent_th), linestyle='dashed')
    d = math.sqrt(math.pow(lookaheadState[0] - test_x, 2) + math.pow(lookaheadState[1] - test_y, 2))
    plt.arrow(test_x, test_y, d*math.cos(global_angle), d*math.sin(global_angle), linestyle='dotted')
    plt.axis('equal')
    plt.title("length = {:.2f}, u = {:.4f}, distance = {:.2f}".format(length[-1], u_star, distance))
    plt.show()
예제 #2
0
def single_spline_main():
    #x = [0, -5.]
    #y = [0., 10.]
    #th = [0., np.pi]
    x = [10., -10.]
    y = [-10., 10.]
    th = [-np.pi/4., -np.pi/4.]
    N = 500
    sx, sy, sth, length, u, coeffs = PiazziSpline.piazziSpline(x[0], y[0], th[0], x[1], y[1], th[1], N=N)
    plt.plot(sx, sy, 'k-', linewidth=2.0)
    test_x = 0.5
    test_y = 0.0

    u_star, closest, distance = closestPointOnSpline2D(length, sx, sy, test_x, test_y, u, coeffs, guess=None)
    #print "closest X = {:.3f}, {:.3f}, u* = {:.2f}".format(closest[0], closest[1], u_star)

    # Figure out the LOS controller using this example
    tangent_th = np.interp(u_star, u, sth)
    #print "tangent th = {:.3f} deg".format(tangent_th*180.0/np.pi)
    lookAhead = 0.01  # how far forward in u
    lookaheadState = splineToEuclidean2D(coeffs, max(0.0, min(u_star + lookAhead, 1.0)))
    #print "lookahead X = {:.3f}, {:.3f}".format(lookaheadState[0], lookaheadState[1])
    dx_global = lookaheadState[0] - closest[0]
    dy_global = lookaheadState[1] - closest[1]
    #print "dx_global = {:.3f}, dy_global = {:.3f}".format(dx_global, dy_global)
    dx_frenet = dx_global*math.cos(tangent_th) + dy_global*math.sin(tangent_th)
    dy_frenet = dx_global*math.sin(tangent_th) - dy_global*math.cos(tangent_th)
    #print "y error = {:.3f}, dx_frenet = {:.3f}, dy_frenet = {:.3f}".format(distance, dx_frenet, dy_frenet)

    # need sign of distance to spline to change
    # look at sign of cross product to determine "handed-ness"
    angle_from_closest_to_test = math.atan2(closest[1] - test_y, closest[0] - test_x)
    #print "angle from closest to test = {:.3f} deg".format(angle_from_closest_to_test*180./np.pi)
    sign_test = np.cross([math.cos(tangent_th), math.sin(tangent_th)], [math.cos(angle_from_closest_to_test), math.sin(angle_from_closest_to_test)])
    distance *= np.sign(sign_test)
    #print "distance to spline after sign update = {:.3f}".format(distance)

    # resulting triangle
    relative_angle = math.atan2((distance - dy_frenet), dx_frenet)
    global_angle = relative_angle + tangent_th
    print "relative angle = {:.3f} deg, global angle = {:.3f} deg".format(relative_angle*180./np.pi, global_angle*180./np.pi)
    u_star, global_angle = LOS_angle(length, sx, sy, sth, u, coeffs, test_x, test_y, lookAhead=lookAhead)
    #print "relative angle = {:.3f} deg, global angle = {:.3f} deg".format(relative_angle*180./np.pi, global_angle*180./np.pi)

    # plot
    plt.plot(test_x, test_y, 'r+', markersize=12., markeredgewidth=2.0)
    plt.plot(closest[0], closest[1], 'gx', markersize=12., markeredgewidth=2.0)
    plt.plot(lookaheadState[0], lookaheadState[1], 'go', markersize=12., markeredgewidth=2.0)
    result_line = np.array([[test_x, test_y], closest])
    lookAhead_line = np.array([closest, lookaheadState])
    plt.plot(result_line[:, 0], result_line[:, 1], 'b-')
    plt.plot(lookAhead_line[:, 0], lookAhead_line[:, 1], 'g-')
    plt.arrow(closest[0], closest[1], 10.*math.cos(tangent_th), 10.*math.sin(tangent_th), linestyle='dashed')
    d = math.sqrt(math.pow(lookaheadState[0] - test_x, 2) + math.pow(lookaheadState[1] - test_y, 2))
    plt.arrow(test_x, test_y, d*math.cos(global_angle), d*math.sin(global_angle), linestyle='dotted')
    plt.axis('equal')
    plt.title("length = {:.2f}, u = {:.4f}, distance = {:.2f}".format(length[-1], u_star, distance))
    plt.show()
예제 #3
0
def closed_spline_chain_main():
    # a chain test
    x = [10, 0, -10, 0]
    y = [0, 10, 0, -10]
    X = np.column_stack((x, y))
    th = [np.pi/2.0, np.pi, -np.pi/2.0, 0]
    Ns = np.random.random_integers(100., 200., (X.shape[0],))
    sx, sy, sth, length, u, coeffs = PiazziSpline.splineClosedChain(X, th, Ns)

    plt.plot(sx, sy, 'k-', linewidth=2.0)
    test_x = 11.0
    test_y = -0.5
    u_star, closest, distance = closestPointOnSpline2D(length, sx, sy, test_x, test_y, u, coeffs, guess=None)
    print "closest X = {:.3f}, {:.3f},  u* = {}".format(closest[0], closest[1], u_star)

    # Figure out the LOS controller using this example
    tangent_th = np.interp(u_star, u, sth)
    print "tangent th = {:.3f} deg".format(tangent_th*180.0/np.pi)
    lookAhead = 0.2  # how far forward in u (remember u goes up to spline_count in a spline chain, not just up to 1)
    wrapped_lookahead = np.mod(u_star + lookAhead, u[-1])  # this will make u wrap around the closed spline
    lookaheadState = splineToEuclidean2D(coeffs, wrapped_lookahead)
    print "lookahead X = {:.3f}, {:.3f}".format(lookaheadState[0], lookaheadState[1])
    dx_global = lookaheadState[0] - closest[0]
    dy_global = lookaheadState[1] - closest[1]
    print "dx_global = {:.3f}, dy_global = {:.3f}".format(dx_global, dy_global)
    dx_frenet = dx_global*math.cos(tangent_th) + dy_global*math.sin(tangent_th)
    dy_frenet = dx_global*math.sin(tangent_th) - dy_global*math.cos(tangent_th)
    print "y error = {:.3f}, dx_frenet = {:.3f}, dy_frenet = {:.3f}".format(distance, dx_frenet, dy_frenet)

    # need sign of distance to spline to change
    # look at sign of cross product to determine "handed-ness"
    angle_from_closest_to_test = math.atan2(closest[1] - test_y, closest[0] - test_x)
    print "angle from closest to test = {:.3f} deg".format(angle_from_closest_to_test*180./np.pi)
    sign_test = np.cross([math.cos(tangent_th), math.sin(tangent_th)], [math.cos(angle_from_closest_to_test), math.sin(angle_from_closest_to_test)])
    distance *= np.sign(sign_test)
    print "distance to spline after sign update = {:.3f}".format(distance)

    # resulting triangle
    relative_angle = math.atan2((distance - dy_frenet), dx_frenet)
    global_angle = tangent_th + relative_angle
    print "relative angle = {:.3f} deg, global angle = {:.3f} deg".format(relative_angle*180./np.pi, global_angle*180./np.pi)

    # plot
    plt.plot(test_x, test_y, 'r+', markersize=12., markeredgewidth=2.0)
    plt.plot(closest[0], closest[1], 'gx', markersize=12., markeredgewidth=2.0)
    plt.plot(lookaheadState[0], lookaheadState[1], 'go', markersize=12., markeredgewidth=2.0)
    result_line = np.array([[test_x, test_y], closest])
    lookAhead_line = np.array([closest, lookaheadState])
    plt.plot(result_line[:, 0], result_line[:, 1], 'b-')
    plt.plot(lookAhead_line[:, 0], lookAhead_line[:, 1], 'g-')
    plt.arrow(closest[0], closest[1], 10.*math.cos(tangent_th), 10.*math.sin(tangent_th), linestyle='dashed')
    d = math.sqrt(math.pow(lookaheadState[0] - test_x, 2) + math.pow(lookaheadState[1] - test_y, 2))
    plt.arrow(test_x, test_y, d*math.cos(global_angle), d*math.sin(global_angle), linestyle='dotted')
    plt.axis('equal')
    plt.title("length = {:.2f}, u = {:.4f}, distance = {:.2f}".format(length[-1], u_star, distance))
    plt.show()