openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

87 lines
2.9 KiB

#!/usr/bin/env python
import numpy as np
from numpy.linalg import inv
from selfdrive.car.honda.interface import CarInterface
## dynamic bycicle model from "The Science of Vehicle Dynamics (2014), M. Guiggiani"##
# Xdot = A*X + B*U
# where X = [v, r], with v and r lateral speed and rotational speed, respectively
# and U is the steering angle (controller input)
#
# A depends on longitudinal speed, u, and vehicle parameters CP
def create_dyn_state_matrices(u, CP):
A = np.zeros((2,2))
B = np.zeros((2,1))
A[0,0] = - (CP.cF + CP.cR)/(CP.m*u)
A[0,1] = - (CP.cF*CP.aF - CP.cR*CP.aR) / (CP.m*u) - u
A[1,0] = - (CP.cF*CP.aF - CP.cR*CP.aR) / (CP.j*u)
A[1,1] = - (CP.cF*CP.aF**2 + CP.cR*CP.aR**2) / (CP.j*u)
B[0,0] = (CP.cF + CP.chi*CP.cR) / CP.m / CP.sR
B[1,0] = (CP.cF*CP.aF - CP.chi*CP.cR*CP.aR) / CP.j / CP.sR
return A, B
def kin_ss_sol(sa, u, CP):
# kinematic solution, useful when speed ~ 0
K = np.zeros((2,1))
K[0,0] = CP.aR / CP.sR / CP.l * u
K[1,0] = 1. / CP.sR / CP.l * u
return K * sa
def dyn_ss_sol(sa, u, CP):
# Dynamic solution, useful when speed > 0
A, B = create_dyn_state_matrices(u, CP)
return - np.matmul(inv(A), B) * sa
def calc_slip_factor(CP):
# the slip factor is a measure of how the curvature changes with speed
# it's positive for Oversteering vehicle, negative (usual case) otherwise
return CP.m * (CP.cF * CP.aF - CP.cR * CP.aR) / (CP.l**2 * CP.cF * CP.cR)
class VehicleModel(object):
def __init__(self, CP, init_state=np.asarray([[0.],[0.]])):
self.dt = 0.1
lookahead = 2. # s
self.steps = int(lookahead / self.dt)
self.update_state(init_state)
self.state_pred = np.zeros((self.steps, self.state.shape[0]))
self.CP = CP
def update_state(self, state):
self.state = state
def steady_state_sol(self, sa, u):
# if the speed is too small we can't use the dynamic model
# (tire slip is undefined), we then use the kinematic model
if u > 0.1:
return dyn_ss_sol(sa, u, self.CP)
else:
return kin_ss_sol(sa, u, self.CP)
def calc_curvature(self, sa, u):
# this formula can be derived from state equations in steady state conditions
sf = calc_slip_factor(self.CP)
return (1. - self.CP.chi)/(1. - sf * u**2) * sa / self.CP.sR / self.CP.l
def get_steer_from_curvature(self, curv, u):
# this function is the exact inverse of calc_curvature, returning steer angle given curvature
sf = calc_slip_factor(self.CP)
return self.CP.l * self.CP.sR * (1. - sf * u**2) / (1. - self.CP.chi) * curv
def state_prediction(self, sa, u):
# U is the matrix of the controls
# u is the long speed
A, B = create_dyn_state_matrices(u, self.CP)
return np.matmul((A * self.dt + np.identity(2)), self.state) + B * sa * self.dt
if __name__ == '__main__':
# load car params
CP = CarInterface.get_params("HONDA CIVIC 2016 TOURING", {})
print CP
VM = VehicleModel(CP)
print VM.steady_state_sol(.1, 0.15)