首页 > 解决方案 > 如何使用纵向动力学模型更新车辆的状态变量?

问题描述

我正在尝试使用 python 类对纵向移动的车辆的动力学进行建模,我的模型应该通过的方程式在下面的图片链接中得到了阐明:

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

我基于以下逻辑构建了我的模型:

  1. 创建一个类。
  2. 将所有状态变量定义为实例属性。
  3. 创建实例方法,该方法接受油门和倾角输入,并逐步通过动力学方程并更新状态变量。

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

  1. 创建一个类实例(对象)
  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

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

以下是一个示例,其中将具有零坡度的恒定油门传递给模型,持续时间为 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()

结果如以下链接中的图像所示:

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

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

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

测评失败!!您的轨迹偏差太大或您的模型不正确!

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

标签: pythonpython-3.xnumpymodeling

解决方案


我可以成功找出错误在哪里,结果证明模型是正确构建的,但是当我将轨迹数据(油门和倾斜角 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()

推荐阅读