Last active
November 2, 2021 08:33
-
-
Save Alexanderallenbrown/e5d2f521b978bb0412ff to your computer and use it in GitHub Desktop.
Bicycle Model implementation in python. linear tires, includes discrete approximation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from numpy import * | |
class BicycleModel: | |
def populate(self): | |
"""this function populates the bicycle model continuous and discrete (tustin) matrices""" | |
#terms for continuous time BM | |
A1 = (self.Cf + self.Cr)/(self.m*self.U) | |
A2 = (self.a*self.Cf-self.b*self.Cr)/(self.m*self.U)-self.U | |
A3 = (self.a*self.Cf-self.b*self.Cr)/(self.I*self.U) | |
A4 = (self.a*self.a*self.Cf+self.b*self.b*self.Cr)/(self.I*self.U) | |
B1 = -self.Cf/self.m | |
B2 = -self.a*self.Cf/self.I | |
#continuous time | |
self.Ac = array([[0, 1, 0, self.U],[0, A1, A2, 0],[0, A3,A4, 0],[0,0,1,0]]) | |
self.Bc = array([[0,0],[B1,-9.81],[B2,0],[0,0]]) | |
#discretize bicycle model using tustin transform | |
prelumped=hstack([self.Ac,self.Bc]) | |
lumped = vstack([prelumped,zeros((2,6))]) | |
lumped_d = dot((eye(6)+.5*self.dT*lumped),linalg.inv((eye(6)-.5*self.dT*lumped))) | |
self.Ad = lumped_d[0:4,0:4] | |
self.Bd = lumped_d[0:4,4:6] | |
def updateMatrices(self,U): | |
"""this function can be used to update the bicycle model for a new forward velocity""" | |
self.U = U | |
self.populate() | |
def updateStates(self,delta,e): | |
""" | |
This function updates states in the discrete model based on delta,superelevation values for the given timestep. | |
""" | |
self.x = dot(self.Ad,self.x)+dot(self.Bd,array([[delta],[e]])) | |
return self.x | |
def __init__(self,a = 1.0,b = 1.0,m = 1000.0,I=2000.0,U=20.0,Cf=-100000.0,Cr=-100000.0,dT=0.01): | |
""" This is a bicycle model. It maintains continuous time and discrete time A,B matrices, and updates states. | |
It includes superelevation and roadwheel angle inputs, and currently needs both to call the update method. | |
""" | |
self.a = a | |
self.b = b | |
self.m = m | |
self.I = I | |
self.U = U | |
self.Cf = Cf | |
self.Cr = Cr | |
self.dT = dT | |
self.x = array([[0],[0],[0],[0]]) | |
self.populate() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment