如何使用纵向动力学模型更新车辆的状态变量?

How to update the state variables of a vehicle using longitudinal dynamics model?

我正在尝试使用 python classes 对纵向移动的车辆的动力学进行建模,我的模型应该逐步通过的方程式在下面的图像 link 中阐明:

https://drive.google.com/file/d/1CK75Q5JzkHM3YRQkWGpI6JojXwhrplD3/view?usp=sharing

我根据以下逻辑构建了我的模型:

  1. 创建 class.
  2. 将所有状态变量定义为实例属性。
  3. 创建实例方法,获取油门和倾角输入并逐步执行动力学方程并更新状态变量。

要使用模型,请遵循以下步骤:

  1. 创建一个class实例(对象)
  2. 定义循环的时间段(开始、停止、步骤)
  3. 创建两个数组,每个数组都包含要在每个时间样本中传递给模型的油门和倾斜角数据
  4. 循环遍历每次调用step方法的时间段,将需要的状态变量保存到一个新的数组中
  5. 绘制所需的状态变量数组 VS 时间

下面的代码部分说明了代码的简要视图:

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

我针对恒定和变化的油门和倾角输入测试了我的模型,它的行为符合预期。 例如,当以零倾斜角逐渐增加油门时,加速度、速度和车轮 angular 速度和加速度也会增加,当倾斜角不为零时,行为会随之变化(即如果它太大使用小油门,汽车将无法移动,因为高负载力会导致负加速度)

以下是一个示例,其中将具有零倾斜度的恒定油门传递给模型,持续时间为 100 秒,采样时间为 0.01 秒,然后绘制速度与时间的关系图:

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()

结果如下图所示link:

https://drive.google.com/open?id=1ldPozpuJI24MPdOb9tnyQI03oHKF3W5f

这在某种程度上是合理的,因为汽车会加速直到力平衡并且速度变得恒定。

coursera-platform 上的评分器提供了所需的轨迹(给定时间段内的特定轨迹和油门和倾角),我被要求将我的模型传递给他们,如上所述,然后保存位置状态的数据变量 (x) 到文件并将其提交给评分系统。但每当我尝试这样做时,它总是输出以下消息:

assessment failed !! your trajectory deviates too much or your model is incorrect !

并且它不提供有关正确结果的任何信息。 我真的找不到错误的来源,也不知道如何解决。 我知道这是一个很长的问题,但我真的需要帮助,有人可以帮忙吗??

我可以成功找出错误所在,事实证明模型构建正确但是当我将轨迹数据(油门和倾斜角alpha)传递到我的模型时我犯了一个大错误,我通过了基于时间样本的模型倾斜角度,而它是根据距离给出的(即,倾斜角度在前 60 米为 0.05 弧度,在接下来的 90 米为 0.1 弧度),但将这些数据输入模型根据经过的时间(即前 5 秒通过 0.05 的倾斜角,接下来的 10 秒通过 0.1 的倾斜角)导致路径略有偏差,因此平地机拒绝了它。 希望有一天这对某人有所帮助,谢谢大家。

这是我最初写的错误代码:

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()

这是正确的代码:

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()