python - 如何使用纵向动力学模型更新车辆的状态变量?
问题描述
我正在尝试使用 python 类对纵向移动的车辆的动力学进行建模,我的模型应该通过的方程式在下面的图片链接中得到了阐明:
https://drive.google.com/file/d/1CK75Q5JzkHM3YRQkWGpI6JojXwhrplD3/view?usp=sharing
我基于以下逻辑构建了我的模型:
- 创建一个类。
- 将所有状态变量定义为实例属性。
- 创建实例方法,该方法接受油门和倾角输入,并逐步通过动力学方程并更新状态变量。
要使用该模型,应遵循以下步骤:
- 创建一个类实例(对象)
- 定义循环的时间段(开始,停止,步骤)
- 创建两个数组,其中包含要在每次采样时传递给模型的油门和倾角数据
- 循环遍历每次调用 step 方法的时间段,并将所需的状态变量保存在新数组中
- 绘制所需的状态变量数组 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) 的数据保存到一个文件并将其提交给评分系统。但每当我尝试这样做时,它总是输出以下消息:
测评失败!!您的轨迹偏差太大或您的模型不正确!
它没有提供任何关于正确结果的信息。我真的不知道错误来自哪里,也不知道如何解决它。我知道这是一个很长的问题,但我真的需要帮助,有人可以帮忙吗?
解决方案
我可以成功找出错误在哪里,结果证明模型是正确构建的,但是当我将轨迹数据(油门和倾斜角 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()
推荐阅读
- android - 单击按钮时关闭当前和上一个活动
- android - Wear OS 和 AlertDialog
- java - Katalon CLI 命令远程执行错误
- python - 在python3中导入期间自动完成模块名称
- reactjs - 如何通过 inputProps 在 Checkbox 组件中添加数据属性
- python-3.x - Keras Bidirectional "RuntimeError: You must compile your model before using it." 编译完成后
- java - 将字符串转换为 jsonArray
- c# - 参数 2 不能与 'out' 关键字一起传递
- angular - 我可以将 ngForm 设置为默认值,但不能设置初始值(angular2+)
- objective-c - 如何在objective-c文件中调用带有转义闭包的swift静态方法