I'm trying to model the dynamics of a vehicle moving longitudinally using python classes, the equations that my model should step through are clarified in the image link below :
https://drive.google.com/file/d/1CK75Q5JzkHM3YRQkWGpI6JojXwhrplD3/view?usp=sharing
I built my model based on the following logic :
to use the model the following steps are to be followed :
a brief view of the code is illustrated in code section bellow :
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
class Vehicle():
def __init__(self):
# ==================================
# Parameters are defined below but i deleted them to shorten the code
# ==================================
#Throttle to engine torque
# Gear ratio, effective radius, mass + inertia
# Aerodynamic and friction coefficients
# Tire force
# State variables
self.x = 0
self.v = 5
self.a = 0
self.w_e = 100
self.w_e_dot = 0
self.sample_time = 0.01
def reset(self):
# reset state variables
self.x = 0
self.v = 5
self.a = 0
self.w_e = 100
self.w_e_dot = 0
def step(self, throttle, alpha):
# calculate F_x, F_load, and T_e respictively
# F_x calculations
w_w = self.GR * self.w_e
slip = ((w_w * self.r_e) - self.v) / self.v
if (slip < 1 and slip > -1):
f_x = self.c * slip
else:
f_x = self.F_max
# F_load calculations
f_aero = self.c_a * (self.v * self.v)
r_x = self.c_r1 * self.v
f_g = self.m * self.g * np.sin(alpha)
f_load = f_aero + r_x + f_g
# T_e calculations
t_e = throttle * (self.a_0 + (self.a_1 * self.w_e) + (self.a_2 * self.w_e**2))
# now update vehicle and engine acceleration rates
self.a = (1 / self.m) * (f_x - f_load)
self.w_e_dot = (1 / self.J_e) * (t_e - (self.GR * self.r_e * f_load))
# now update vehicle position, speed and engine speed according to the updated vehicle and engine acceleration rates
# using newton's formulas of motion (assuming constant acceleration during sample time )
self.x = (self.v * self.sample_time) + (0.5 * self.a * self.sample_time**2) + self.x
self.v = (self.a * self.sample_time) + self.v
self.w_e = (self.w_e_dot * self.sample_time) + self.w_e
i tested my model for both constant and varying throttle and inclination angle inputs and it behaves as expected. for example when gradually increase the throttle with a zero incline angle, the acceleration, speed and wheel angular speed and acceleration also increase, when the inclination angle is not zero the behavior varies according to it (i.e. if it were so big with a small throttle the car wouldn't be able to move due to high load forces which causes negative acceleration)
the following is an example where a constant throttle with a zero incline were passed to the model for time period of 100 seconds with a sample time of 0.01 second and then plot the speed vs time :
sample_time = 0.01
time_end = 100
model = Vehicle()
t_data = np.arange(0,time_end,sample_time)
v_data = np.zeros_like(t_data)
# throttle percentage between 0 and 1
throttle = 0.2
# incline angle (in radians)
alpha = 0
for i in range(t_data.shape[0]):
v_data[i] = model.v
model.step(throttle, alpha)
plt.plot(t_data, v_data)
plt.show()
the result is illustrated in the image in the following link :
https://drive.google.com/open?id=1ldPozpuJI24MPdOb9tnyQI03oHKF3W5f
which is somehow reasonable because the car accelerates until forces are balanced and the speed becomes constant.
the grader on coursera-platform provides a desired trajectory (specific and throttle and inclination angle for a given time period) and i'm asked to pass them my model as mentioned above and then save the data of the position state variable (x) to a file and submit it to the grading system. but it always outputs the following message whenever i try to do so:
assessment failed !! your trajectory deviates too much or your model is incorrect !
and it does not offer any information about the correct results. i really can't find out where the error is coming from and have no idea how to fix it. i know it's a very long question but i really need help, can anyone help please??
I could successfully find out where the error was, it turned out that the model was build correctly but i made a big mistake when i passed the trajectory data (throttle and inclination angle alpha) into my model, i passed the incline angle to the model based on time samples while it was given based on the distance (i.e. it was given that the incline angle was 0.05 rad for the first 60 meters and 0.1 rad for the next 90 meters) but fed these data into the model according to time passed (i.e. for the first 5 seconds pass an incline angle of .05 and for the next 10 seconds pas an incline angle of 0.1) which caused a slight deviation in the path and as a result the grader refused it. hope this helps someone one day, thanks all.
here is the code i wrote first which was wrong :
time_end = 20
t_data = np.arange(0,time_end,sample_time)
x_data = np.zeros_like(t_data)
throttle_data = np.zeros_like(t_data)
alpha_data = np.zeros_like(t_data)
# reset the states
model.reset()
# ==================================
# Learner solution begins here
# ==================================
# throttle profile
for i in range(499):
throttle_data[i] = (0.06*sample_time*i) + 0.2
throttle_data[500:1499] = 0.5
for i in range(1500,1999):
throttle_data[i] = 2 - (0.1*sample_time*i)
# incline angle profile (in radians)
alpha_data[0:499] = np.arctan(3/60)
alpha_data[500:1499] = np.arctan(9/90)
alpha_data[1500:1999] = 0
for i in range(t_data.shape[0]):
x_data[i] = model.x
model.step(throttle_data[i], alpha_data[i])
# ==================================
# Learner solution ends here
# ==================================
# Plot x vs t for visualization
plt.plot(t_data, x_data)
plt.show()
and this is the correct code :
time_end = 20
t_data = np.arange(0,time_end,sample_time)
x_data = np.zeros_like(t_data)
# reset the states
model.reset()
# ==================================
# Learner solution begins here
# ==================================
for i in range(t_data.shape[0]):
x_data[i] = model.x
if t_data[i] < 5:
throttle = (0.3/5)*t_data[i] + 0.2
else:
if t_data[i] < 15:
throttle = 0.5
else:
throttle = (-0.5/5)*t_data[i] + 2
if x_data[i] < 60:
alpha = 0.0499583957
else:
if x_data[i] < 150:
alpha = 0.0996686525
else:
alpha = 0
model.step(throttle, alpha)
# ==================================
# Learner solution ends here
# ==================================
# Plot x vs t for visualization
plt.plot(t_data , x_data)
plt.show()