def matlab_steering_simulation():
  '''Non-linear steering simulation converted from MATLAB code.''' 
  # Trajectory tracking
  # Fixed vehicle parameters
  v = 5  # Speed
  delta_max = 25 * math.pi / 180  # max steering angle
  k = 2.5  # Gain
  l = 0.238  # Car length

  # Desired line state through 0,0 [theta]
  xp = 0  # Line heading

  # Initial conditions in [e psi]
  x0 = np.mat([5, 0])  # translational offset
  #x0 = [0 2]; # heading offset
  #x0 = mat([5, 2])  # both

  # Simulation time
  Tmax = 3  # End point
  dt = 0.001  # Time step
  T = np.arange(0, Tmax, dt)  # Time vector

  # Simulation setup
  xd = np.mat(np.zeros((len(T) - 1, 2)))  # Derivative of state ([edot psidot])
  x = np.mat(np.zeros((len(T), 2)))  # State ([e psi])
  x[0, :] = x0  # Initial condition
  delta = np.mat(np.zeros((len(T), 1)))  # Steering angles
  p = np.mat(np.zeros((len(T), 2)))  # Position in x,y plane
  p[0, :] = x0[0, 0] * np.mat([np.sin(xp), np.cos(xp)])  # Initial position

  for i in xrange(len(T) - 1):
    # Calculate steering angle
    delta[i] = max(-delta_max, min(delta_max,
                                   x[i, 1] + np.arctan2(k * x[i, 0], v)))
    # State derivatives
    xd[i, 0] = v * np.sin(x[i, 1] - delta[i])
    xd[i, 1] = -(v * np.sin(delta[i])) / l
    # State update
    x[i + 1, 0] = x[i, 0] + dt * xd[i, 0]
    x[i + 1, 1] = x[i, 1] + dt * xd[i, 1]
    # Position update
    p[i + 1, 0] = p[i, 0] + dt * v * np.cos(x[i, 1] - delta[i] - xp)
    p[i + 1, 1] = p[i, 1] + dt * v * np.sin(x[i, 1] - delta[i] - xp)

  ## Plotting

  # Trajectory
  pyplot.figure(1)
  pyplot.clf()
  pyplot.hold(True)

  pyplot.plot([0, Tmax * v * np.cos(xp)], [0, Tmax * v * np.sin(xp)], 'b--')
  pyplot.plot(x0[0, 0] * np.sin(x0[0, 1]), x0[0, 0] * np.cos(x0[0, 1]))
  pyplot.plot(p[:, 0], p[:, 1], 'r')

  for t in xrange(0, len(T), 300):
    draw.drawbox(p[t, 0], p[t, 1], x[t, 1], .3, 1);

  pyplot.xlabel('x (m)')
  pyplot.ylabel('y (m)')
  pyplot.axis('equal')

  # Phase portrait
  (e, psi) = np.meshgrid(np.arange(-10, 10.5, .5), np.arange(-3, 3.2, .2))  # Create a grid over values of e and psi
  delta = np.maximum(-delta_max, np.minimum(delta_max, psi + np.arctan2(k * e, v)))  # Calculate steering angle at each point
  ed = v * np.sin(psi - delta)  # Find crosstrack derivative
  psid = -(v * np.sin(delta)) / l  # Find heading derivative

  psibplus = -np.arctan2(k * e[0, :], v) + delta_max  # Find border of max region
  psibminus = -np.arctan2(k * e[0, :], v) - delta_max  # Find border of min region

  pyplot.figure(2)
  pyplot.clf
  pyplot.hold(True)
  pyplot.quiver(e, psi, ed, psid)
  pyplot.plot(e[0, :], psibplus, 'r', linewidth=2)
  pyplot.plot(e[0, :], psibminus, 'r', linewidth=2)
  pyplot.axis([-10, 10, -3, 3])
  pyplot.xlabel('e (m)')
  pyplot.ylabel('\psi (rad)')

  pyplot.show()
def stanley_steering_simulation(waypts):
  '''Stanley steering simulation.

  Args:
    waypts: The waypoints in which the robot should move through.
  '''
  # Vehicle parameters
  v = 0.4  # Speed
  delta_max = 15 * math.pi / 180  # max steering angle
  k = 0.25  # Gain
  l = 0.238  # Car length

  # Initial conditions
  x0 = np.array([0, 45 * math.pi / 180, 0])

  # Setup the simulation time
  Tmax = 60*1.5
  dt = 0.001
  T = np.arange(0, Tmax, dt)

  # Setup simulation
  xd = np.zeros((len(T) - 1, 3))  # Derivative of state
  x = np.zeros((len(T), 3))  # State
  x[0, :] = x0  # Initial condition
  delta = np.zeros((len(T), 1))
  p = np.zeros((len(T), 2))
  p[0, :] = [0, 0]  # Initial position
  waypt = 0

  for i in xrange(len(T) - 1):
    # Steering calculation
    steering = controller.stanley_steering(
        waypts[waypt:waypt + 3],
        p[i, :],
        x[i, 1],
        v,
        k,
        )
    waypt = waypt + steering['waypt']
    delta[i] = max(-delta_max, min(delta_max, steering['angle']))
    # PLEASE MAKE SURE THIS IS CORRECT AND ALL
    # State derivatives
    xd[i, 0] = v * np.sin(x[i, 1] - delta[i])
    xd[i, 1] = -(v * np.sin(delta[i])) / l
    # State update
    x[i + 1, 0] = x[i, 0] + dt * xd[i, 0]
    x[i + 1, 1] = x[i, 1] + dt * xd[i, 1]
    # Position update
    p[i + 1, 0] = p[i, 0] + dt * v * np.cos(x[i, 1] - delta[i])
    p[i + 1, 1] = p[i, 1] + dt * v * np.sin(x[i, 1] - delta[i])


  ## Plotting

  # Trajectory
  pyplot.figure(1)
  pyplot.clf()
  pyplot.hold(True)

  pyplot.plot(x0[0] * np.sin(x0[1]), x0[0] * np.cos(x0[1]))
  pyplot.plot(p[:, 0], p[:, 1], 'r')
  pyplot.plot([pt[0] for pt in waypts], [pt[1] for pt in waypts], 'go')

  for t in xrange(0, len(T), 300):
    draw.drawbox(p[t, 0], p[t, 1], x[t, 1], .3, 1);

  pyplot.xlabel('x (m)')
  pyplot.ylabel('y (m)')
  pyplot.axis('equal')
  pyplot.show()
Ejemplo n.º 3
0
def stanley_steering_simulation(waypts):
  '''Stanley steering simulation.

  Args:
    waypts: The waypoints in which the robot should move through.
  '''
  # Vehicle parameters
  v = 0.4  # Speed
  delta_max = 15 * math.pi / 180  # max steering angle
  k = 0.25  # Gain
  l = 0.238  # Car length

  # Initial conditions [e, psi]
  x0 = np.array([0, 45 * math.pi / 180])

  # Setup the simulation time
  Tmax = 45  # in seconds
  dt = 0.001  # time step
  T = np.arange(0, Tmax, dt)

  # Setup simulation
  xd = np.zeros((len(T) - 1, 2))  # Derivative of state
  x = np.zeros((len(T), 2))  # State
  x[0, :] = x0  # Initial condition
  delta = np.zeros((len(T), 1)) # Angle change
  p = np.zeros((len(T), 2))  # Position
  p[0, :] = [0, 0]  # Initial position
  waypt = 0 # Initial waypoint to travel from

  for i in xrange(len(T) - 1):
    # Steering calculation
    steering = controller.stanley_steering(
        waypts[waypt:waypt + 3],
        p[i, :],
        x[i, 1],
        v,
        k,
        )
    waypt = waypt + steering['waypt']
    delta[i] = max(-delta_max, min(delta_max, steering['angle']))

    # State derivatives
    xd[i, 0] = v * np.sin(x[i, 1] - delta[i])
    xd[i, 1] = -(v * np.sin(delta[i])) / l
    # State update
    x[i + 1, 0] = x[i, 0] + dt * xd[i, 0]
    x[i + 1, 1] = x[i, 1] + dt * xd[i, 1]
    # Position update
    p[i + 1, 0] = p[i, 0] + dt * v * np.cos(x[i, 1] - delta[i])
    p[i + 1, 1] = p[i, 1] + dt * v * np.sin(x[i, 1] - delta[i])


  ## Plotting
  # Trajectory

  # Setup trajectory plot
  pyplot.figure(1)
  pyplot.clf()
  pyplot.hold(True)
  pyplot.xlabel('x (m)')
  pyplot.ylabel('y (m)')
  pyplot.axis('equal')

  # Plot trajectory
  pyplot.plot(x0[0] * np.sin(x0[1]), x0[0] * np.cos(x0[1]))
  pyplot.plot(p[:, 0], p[:, 1], 'r')
  pyplot.plot([pt[0] for pt in waypts], [pt[1] for pt in waypts], 'go')

  for t in xrange(0, len(T), 300):
    draw.drawbox(p[t, 0], p[t, 1], x[t, 1], .3, 1);


  # Phase portrait
  # Create a grid over values of e and psi
  e, psi = np.meshgrid(np.arange(-10, 10, .5), np.arange(-3, 3, .2))
  # Calculate steering angle at each point
  delta = np.maximum(-delta_max,
                     np.minimum(delta_max, psi + np.arctan2(k * e, v)))
  ed = v * np.sin(psi - delta)  # Find crosstrack derivative
  psid = -(v * np.sin(delta)) / l  # Find heading derivative

  # Find border of max region
  psibplus = -np.arctan2(k * e[0, :], v) + delta_max
  # Find border of min region
  psibminus = -np.arctan2(k * e[0, :], v) - delta_max

  # Setup phase portrait plot
  pyplot.figure(2)
  pyplot.clf()
  pyplot.hold(True)
  pyplot.axis([-10, 10, -3, 3])
  pyplot.xlabel('e (m)')
  pyplot.ylabel('\psi (rad)')

  # Plot phase portrait
  pyplot.quiver(e, psi, ed, psid)
  pyplot.plot(e[0, :], psibplus, 'r', linewidth=2)
  pyplot.plot(e[0, :], psibminus, 'r', linewidth=2)

  pyplot.show()