def ctrl_traj(x, y, th, ctrl_prev, x_d, y_d, xd_d, yd_d, xdd_d, ydd_d, x_g,
              y_g, th_g):
    # (x,y,th): current state
    # ctrl_prev: previous control input (V,om)
    # (x_d, y_d): desired position
    # (xd_d, yd_d): desired velocity
    # (xdd_d, ydd_d): desired acceleration
    # (x_g,y_g,th_g): desired final state

    # Timestep
    dt = 0.005

    # Gains
    kpx = 1
    kpy = 1
    kdx = 0.5
    kdy = 0.5

    # Cutoffs
    d_eps = 0.5  # Switch to pose controller
    V_eps = 1e-5  # Reset to nominal velocity

    # Define control inputs (V,om) - without saturation constraints
    # Switch to pose controller once "close" enough, i.e., when
    # the robot is within 0.5m of the goal xy position.
    if np.sqrt((x_g - x)**2 + (y_g - y)**2) <= d_eps:
        return ctrl_pose(x, y, th, x_g, y_g, th_g)

    # Assume current velocity is that commanded in previous timestep
    V_prev = ctrl_prev[0]
    x_dot = V_prev * np.cos(th)
    y_dot = V_prev * np.sin(th)

    # Virtual control law
    u1 = xdd_d + kpx * (x_d - x) + kdx * (xd_d - x_dot)
    u2 = ydd_d + kpy * (y_d - y) + kdy * (yd_d - y_dot)

    # Recover actual control inputs
    V_dot = u1 * np.cos(th) + u2 * np.sin(th)
    V = V_prev + dt * V_dot  # Euler step

    # Reset to desired velocity if V = 0
    if np.abs(V) <= V_eps:
        V = np.sqrt(xd_d**2 + yd_d**2)
        print "Resetting to nominal velocity: ", V
    om = (-u1 * np.sin(th) + u2 * np.cos(th)) / V

    # Apply saturation limits
    V = np.sign(V) * min(0.5, np.abs(V))
    om = np.sign(om) * min(1, np.abs(om))

    return np.array([V, om])
Exemple #2
0
def ctrl_traj(x, y, th, ctrl_prev, x_d, y_d, xd_d, yd_d, xdd_d, ydd_d, x_g,
              y_g, th_g):
    # (x,y,th): current state
    # ctrl_prev: previous control input (V,om)
    # (x_d, y_d): desired position
    # (xd_d, yd_d): desired velocity
    # (xdd_d, ydd_d): desired acceleration
    # (x_g,y_g,th_g): desired final state

    # Timestep
    dt = 0.005

    # Gains
    kpx = 1.0
    kpy = 1.0
    kdx = 2.0
    kdy = 2.0

    # Distance form current pos to the target
    dist = np.sqrt((x_g - x)**2 + (y_g - y)**2)
    # Define control inputs (V,om) - without saturation constraints
    # Switch to pose controller once "close" enough, i.e., when
    # the robot is within 0.5m of the goal xy position.
    if dist <= 0.5:
        V, om = ctrl_pose(x, y, th, x_g, y_g, th_g)
    else:
        if abs(ctrl_prev[0]) <= 1e-5:
            V_prev = np.sign(ctrl_prev[0]) * 1e-5
        else:
            V_prev = ctrl_prev[0]

        x_dot = V_prev * np.cos(th)
        y_dot = V_prev * np.sin(th)

        # virtual control inputs
        u = np.array([
            xdd_d + kpx * (x_d - x) + kdx * (xd_d - x_dot),
            ydd_d + kpy * (y_d - y) + kdy * (yd_d - y_dot)
        ])

        J = np.array([[np.cos(th), -V_prev * np.sin(th)],
                      [np.sin(th), V_prev * np.cos(th)]])
        a, om = np.linalg.solve(J, u)
        V = V_prev + a * dt

    # Apply saturation limits
    V = np.sign(V) * min(0.5, np.abs(V))
    om = np.sign(om) * min(1, np.abs(om))

    return np.array([V, om])
def ctrl_traj(x, y, th, ctrl_prev, x_d, y_d, xd_d, yd_d, xdd_d, ydd_d, x_g,
              y_g, th_g):
    # (x,y,th): current state
    # ctrl_prev: previous control input (V,om)
    # (x_d, y_d): desired position
    # (xd_d, yd_d): desired velocity
    # (xdd_d, ydd_d): desired acceleration
    # (x_g,y_g,th_g): desired final state

    # Timestep
    dt = 0.005

    # Gains
    kpx = 0.9
    kpy = 0.9
    kdx = 0.7
    kdy = 0.7

    # Define control inputs (V,om) - without saturation constraints
    # Switch to pose controller once "close" enough, i.e., when
    # the robot is within 0.5m of the goal xy position.
    if (math.sqrt((x - x_d)**2 + (y - y_d)**2) > 0.0):
        # Use virtual control law
        V_prev = ctrl_prev[0]
        om_prev = ctrl_prev[1]
        xd = V_prev * math.cos(th)
        yd = V_prev * math.sin(th)
        u1 = xdd_d + kpx * (x_d - x) + kdx * (xd_d - xd)
        u2 = ydd_d + kpy * (y_d - y) + kdy * (yd_d - yd)

        Vd = u1 * math.cos(th) + u2 * math.sin(th)
        V = V_prev + Vd * dt
        if V <= 0:
            V = math.sqrt(xd_d**2 + yd_d**2)  # reset to nominal velocity
        om = (u2 * math.cos(th) - u1 * math.sin(th)) / V

    else:
        # Use pose controller from problem 3
        ctrl = ctrl_pose(x, y, th, x_g, y_g, th_g)
        V = ctrl[0]
        om = ctrl[1]

    # Apply saturation limits
    V = np.sign(V) * min(0.5, np.abs(V))
    om = np.sign(om) * min(1, np.abs(om))

    return np.array([V, om])
Exemple #4
0
#timestep
dt = 0.005
N = int (t_end/dt)

# Set up simulation

time = dt * np.array(range(N+1)) 
state = np.zeros((N+1,3))
state[0,:] = np.array([[x_0, y_0, th_0]])
x = state[0,:]

ctrl = np.zeros((N,2))

for i in range(N): 
    ctrl_fbck = ctrl_pose(x[0], x[1], x[2], x_g, y_g, th_g)
    ctrl[i,0] = ctrl_fbck[0]
    ctrl[i,1] = ctrl_fbck[1]

    d_state = odeint(car_dyn, x, np.array([time[i], time[i+1]]), args=(ctrl[i,:], [0,0]) )
    x = d_state[1,:]
    state[i+1,:] = x

# Plots
maybe_makedirs('plots')
plt.figure(figsize=(15,5))
plt.subplot(1,3,1)
plt.plot(state[:,0],state[:,1],linewidth=1)
plt.title('Trajectory')
plt.quiver(state[0:-1:200,0],state[0:-1:200,1],np.cos(state[0:-1:200,2]), np.sin(state[0:-1:200,2]))
plt.grid('on')
Exemple #5
0
def ctrl_traj(x, y, th, ctrl_prev, x_d, y_d, xd_d, yd_d, xdd_d, ydd_d, x_g,
              y_g, th_g):
    '''
    This function computes the closed-loop control law.
    Inputs:
        (x,y,th): current state
        ctrl_prev: previous control input (V,om)
        (x_d, y_d): desired position
        (xd_d, yd_d): desired velocity
        (xdd_d, ydd_d): desired acceleration
        (x_g,y_g,th_g): desired final state
    Outputs:
        (V, om): a numpy array np.array([V, om]) containing the desired control inputs
    '''

    # Timestep
    dt = 0.005

    ########## Code starts here ##########

    kpx = 1
    kpy = 1
    kdx = 2
    kdy = 2

    dist_from_goal = np.sqrt((x_g - x)**2 + (y_g - y)**2)

    if (dist_from_goal < 0.5):
        # switch control laws because we're close to the goal
        [V, om] = ctrl_pose(x, y, th, x_g, y_g, th_g)
    else:

        # Set up and solve for a, w
        V_prev = ctrl_prev[0]
        w_prev = ctrl_prev[1]

        xdot = V_prev * np.cos(th)
        ydot = V_prev * np.sin(th)

        u1 = xdd_d + kpx * (x_d - x) + kdx * (xd_d - xdot)
        u2 = ydd_d + kpy * (y_d - y) + kdy * (yd_d - ydot)

        J = np.array([[np.cos(th), -V_prev * np.sin(th)],
                      [np.sin(th), V_prev * np.cos(th)]])

        u = np.array([u1, u2])

        aw = linalg.solve(J, u)

        a = aw[0]
        om = aw[1]

        # Integrate to obtain V
        V = V_prev + a * dt

        #reset V if it becomes 0 to avoid singularity
        if (abs(V) < 0.01):
            V = np.sqrt((xd_d - xdot)**2 + (yd_d - xdot)**2)

        #Apply saturation limits
        V = np.sign(V) * min(0.5, abs(V))
        om = np.sin(om) * min(1.0, abs(om))

    ########## Code ends here ##########

    return np.array([V, om])
Exemple #6
0
def ctrl_traj(x, y, th, ctrl_prev, x_d, y_d, xd_d, yd_d, xdd_d, ydd_d, x_g,
              y_g, th_g):
    '''
    This function computes the closed-loop control law.
    Inputs:
        (x,y,th): current state
        ctrl_prev: previous control input (V,om)
        (x_d, y_d): desired position
        (xd_d, yd_d): desired velocity
        (xdd_d, ydd_d): desired acceleration
        (x_g,y_g,th_g): desired final state
    Outputs:
        (V, om): a numpy array np.array([V, om]) containing the desired control inputs
    '''

    # Timestep
    dt = 0.005

    ########## Code starts here ##########
    # Let's set gains
    kpx = 1.5
    kpy = 1.0
    kdx = 2.5
    kdy = 2.0

    rho = np.sqrt(
        (x_g - x)**2 +
        (y_g - y)**2)  # Distance between current position and goal position

    # If the robot is sufficiently close (rho <= 0.5); switch to pose stabilisation controller from Problem 3
    if rho <= 0.5:
        V, om = ctrl_pose(x, y, th, x_g, y_g, th_g)
    else:  # Dealing with singularity
        if abs(ctrl_prev[0]) <= 1e-6:
            V_ = np.sign(ctrl_prev[0]) * 1e-6
        else:
            V_ = ctrl_prev[0]

        xd = V_ * np.cos(th)
        yd = V_ * np.sin(th)

        #Adding control inputs
        # As shown in the equation in Problem #2
        u = np.array([
            xdd_d + kpx * (x_d - x) + kdx * (xd_d - xd),
            ydd_d + kpy * (y_d - y) + kdy * (yd_d - yd)
        ])
        J = np.array([[np.cos(th), -V_ * np.sin(th)],
                      [np.sin(th), V_ * np.cos(th)]])

        a, om = np.linalg.solve(J, u)
        V = V_prev + a * dt

    # Keeping V < 0.5 and om < 1
    V_max = 0.5
    om_max = 1
    om = np.sign(om) * min(om_max, np.abs(om))
    V = np.sign(V) * min(V_max, np.abs(V))

    ########## Code ends here ##########

    return np.array([V, om])