1、车辆运动学基础:坐标系定义、车辆位姿描述、刚体运动与旋转矩阵

各位同学好,我是你们的车辆工程讲师。今天咱们来聊聊车辆运动学的基础。说实话,这部分内容看着有点数学化,但它是后续所有动力学分析的根基。我在做车辆稳定性控制项目时,就曾因为坐标系没统一,导致仿真结果跟实车测试对不上,折腾了整整一周才找到问题。

所以,咱们先把地基打牢。

1.1 坐标系定义——你得知道车在哪儿、往哪儿走

描述车辆运动,首先得有个参考系。我个人习惯把坐标系分成两大类:全局坐标系车辆坐标系

  • 全局坐标系(大地坐标系):固定在地面上,通常用 X 轴指向东、Y 轴指向北、Z 轴垂直向上。说白了,就是给地球画个三维网格。
  • 车辆坐标系(车身坐标系):固定在车身上。原点一般在车辆质心或后轴中心。x 轴指向车头前方,y 轴指向驾驶员左侧,z 轴垂直向上。

你想想看,如果我说“车辆速度是 10 m/s”,这速度是相对于地面的,还是相对于空气的?所以定义清楚坐标系,是第一步。

重要原则:所有运动学量(位置、速度、加速度)都必须明确其参考坐标系。我在项目中见过有人把车身坐标系下的加速度直接当成全局加速度用,结果控制算法全乱了。

1.2 车辆位姿描述——光有位置不够,还得知道朝向

车辆在平面上运动,它的状态用三个量就够了:(x, y, θ)

  • xy:车辆在全局坐标系中的位置。
  • θ:车辆的航向角,也就是车头方向与全局 X 轴的夹角。

嗯,这里要注意:航向角通常逆时针为正。我刚开始做路径规划时,把正负号搞反了,车一直往反方向跑,当时还以为传感器坏了。

对于三维空间中的车辆(比如考虑坡道),位姿描述就更复杂了,需要用到 欧拉角:横摆角(Yaw)、俯仰角(Pitch)、侧倾角(Roll)。

欧拉角 旋转轴 描述
横摆角 (ψ) Z 轴 车辆绕垂直轴的旋转,即转向
俯仰角 (θ) Y 轴 车辆抬头或点头,如上坡下坡
侧倾角 (φ) X 轴 车辆左右倾斜,如过弯时

避坑指南:我曾经在仿真中直接用欧拉角做插值,结果出现了“万向锁”现象,车辆姿态突然跳变。后来改用四元数才解决。如果你做的是大角度运动(比如翻车测试),建议直接上四元数。

1.3 刚体运动与旋转矩阵——数学工具,但很实用

车辆可以近似看作一个刚体。刚体运动 = 平移 + 旋转。

平移很简单,就是位置坐标加减。旋转呢?就得靠 旋转矩阵 了。

假设车辆坐标系下有一个点 P,坐标为 (x_v, y_v)。我想知道它在全局坐标系下的坐标 (X_g, Y_g)。如果车辆航向角是 θ,那么:

X_g = x_v * cos(θ) - y_v * sin(θ) + X_car
Y_g = x_v * sin(θ) + y_v * cos(θ) + Y_car

写成矩阵形式更清爽:

[X_g]   [cosθ  -sinθ] [x_v]   [X_car]
[Y_g] = [sinθ   cosθ] [y_v] + [Y_car]

前面那个 2x2 矩阵,就是二维旋转矩阵 R(θ)

三维情况类似,只是矩阵变成了 3x3。比如绕 Z 轴旋转 ψ 角:

R_z(ψ) = [cosψ  -sinψ  0]
         [sinψ   cosψ  0]
         [0      0     1]

核心性质:旋转矩阵是正交矩阵,它的逆等于它的转置。这意味着从全局坐标系转到车辆坐标系,只需要把矩阵转置一下就行。这个性质在传感器数据融合时特别有用。

1.4 实际应用——从理论到代码

光讲理论没意思,咱们看看代码怎么写。下面是一个简单的 Python 示例,演示如何将车辆坐标系下的点转换到全局坐标系:

import numpy as np

def vehicle_to_global(x_v, y_v, theta, X_car, Y_car):
    """
    将车辆坐标系下的点转换到全局坐标系
    :param x_v, y_v: 车辆坐标系下的点坐标
    :param theta: 车辆航向角 (弧度)
    :param X_car, Y_car: 车辆在全局坐标系中的位置
    :return: 全局坐标系下的坐标 (X_g, Y_g)
    """
    R = np.array([[np.cos(theta), -np.sin(theta)],
                  [np.sin(theta),  np.cos(theta)]])
    point_v = np.array([x_v, y_v])
    point_g = R @ point_v + np.array([X_car, Y_car])
    return point_g

# 举个例子:车辆在 (10, 5),航向角 30度
# 车上有个传感器在 (1, 0.5) 处
result = vehicle_to_global(1, 0.5, np.radians(30), 10, 5)
print(f"传感器全局位置: ({result[0]:.2f}, {result[1]:.2f})")
# 输出: 传感器全局位置: (10.87, 5.87)

这段代码我用了很多次,从路径规划到传感器仿真,都离不开它。

1.5 小结与思考

这一章咱们讲了三个核心概念:

  1. 坐标系:全局坐标系和车辆坐标系,搞混了会出大问题。
  2. 位姿描述:位置 + 朝向,二维用 (x, y, θ),三维用欧拉角或四元数。
  3. 旋转矩阵:连接两个坐标系的数学桥梁,正交矩阵性质要牢记。

最后留个思考题:如果车辆在坡道上行驶,俯仰角为 10 度,侧倾角为 5 度,你如何将车辆坐标系下的一个点转换到全局坐标系?提示:需要组合三个旋转矩阵,顺序很重要。

下一章咱们聊车辆运动学模型,就是那个经典的自行车模型。到时候你会发现,今天这些基础全都能用上。