刹车距离核算

这一页解决什么问题

跟车太近、雨天不减速、下坡不提前刹车,本质都是同一个问题:没人算过「以这个速度,从看见到停住要多少米」。

这个公式(反应距离 + 制动距离)在驾校教材里就有,但工程里它通常散落在设计文档的几张表格里,换个车速、换个路面就得重查。本页给出一个纯物理、纯标准库的实现:输入车速、反应时间、附着系数与坡度,直接算出三个可加和的量,并用四条断言判断这次跟车/接近是否安全。

本页原来只有一条参考链接。下面的实现是在同一主题下补的:不依赖 CARLA、不需要 GPU、不需要显示器,一条命令在终端出结果,方便在没有仿真环境的机器上做回归。

自主实现:braking_distance_check

目录结构

src/ground/braking_distance_check/
├── CMakeLists.txt
├── package.xml
├── README.md
├── config/braking_distance_check.yaml   # 10 个参数默认值
├── launch/main.launch                   # 10 个带 doc 的 arg
└── scripts/
    ├── main.py                          # roslaunch 的入口
    ├── braking_core.py                  # 纯物理计算(不 import rospy)
    └── braking_node.py                  # ROS 收发放这里
tests/test_braking_distance_check_local.py

公式

量 公式 默认工况下(50 km/h、μ = 0.70、反应 1 s)
初速换算 v0 = speed_kmh / 3.6 13.889 m/s
反应距离 v0 * t_r 13.89 m
制动减速度 a = μ g cosθ + g sinθ 6.87 m/s²
制动距离 v0² / (2a) 14.05 m
停车距离 反应距离 + 制动距离 27.93 m
刹停耗时 v0 / a 2.02 s
两秒法则车距 v0 * 2 + 余量(3 m) 30.78 m

两点值得注意:

  1. 制动距离与速度是平方关系。 50 → 100 km/h 时制动距离从 14.05 m 涨到 56.18 m(四倍),完整对照见下文的速度表。这就是「高速上一脚刹车根本不够」的算术解释。
  2. 坡度直接进减速度。 上坡时 g sinθ 帮忙,下坡时变成负数。默认 0 度,所以只剩 μ g。

四条断言

断言 判据 不过时的含义
停车距离 停车距离 ≤ 前方可用距离 到前车/障碍物之前停不住
跟车间距 车距 ≥ 两秒法则要求 跟得太紧,前车急刹就追尾
路面附着 μ ≥ 0.30 雪/冰/积水路面,物理上就停不住
限速 车速 ≤ 路段限速 超速

四条互相独立:换一个参数只会让相关的那条翻转,便于定位到底是哪里不够。

参数表

参数 默认 说明
scene/speed_kmh 50.0 当前车速
scene/available_distance 40.0 前方可用距离(到前车或障碍物)
scene/gap 32.0 当前跟车间距
vehicle/reaction_time 1.00 反应时间(含抬脚换踏板)
vehicle/speed_limit_kmh 60.0 该路段限速
road/friction 0.70 附着系数:干沥青 0.7~0.9、湿 0.4、雪 0.2、冰 0.1
road/slope_deg 0.0 坡度,正为上坡
rate/publish_hz 1.0 报告重发频率
topic/report /braking/report 报告话题(std_msgs/String)
topic/bars /braking/bars 距离字符条话题(std_msgs/String)

话题表

话题 类型 方向 说明
/braking/report std_msgs/String 发布(latched) 距离分解 + 四条断言 + 车速对照表
/braking/bars std_msgs/String 发布(latched) 一条字符条:= 反应距离、# 制动距离、- 前方尚可用

运行

cd ~/catkin_ws8
source /opt/ros/melodic/setup.bash
source devel/setup.bash
roslaunch braking_distance_check main.launch

默认工况(50 km/h、干沥青、反应 1 s、前方 40 m、车距 32 m)的实际输出:

刹车距离核算(内置物理模型,不依赖 CARLA)
工况:车速 50.0 km/h(13.889 m/s),反应时间 1.00 s,路面 μ = 0.70,坡度 +0.0 度
减速:可用制动减速度 6.87 m/s^2,刹停耗时 2.02 s
距离:反应 13.89 m + 制动 14.05 m = 停车 27.93 m
断言:4 通过 / 0 失败(共 4 条)
  [PASS] 停车距离   需要 27.93 m,前方可用 40.00 m
  [PASS] 跟车间距   当前 32.00 m,两秒法则要求 30.78 m
  [PASS] 路面附着   μ = 0.70,对应减速度 6.87 m/s^2,下限 μ = 0.30
  [PASS] 限速     当前 50.0 km/h,限速 60.0 km/h
车速对照(同一路面、同一反应时间):
     30 km/h -> 反应  8.33 + 制动  5.06 = 13.39 m  够
     50 km/h -> 反应 13.89 + 制动 14.05 = 27.93 m  够
     80 km/h -> 反应 22.22 + 制动 35.96 = 58.18 m  不够
    100 km/h -> 反应 27.78 + 制动 56.18 = 83.96 m  不够
结论:PASSED

后面还跟一条字符条,把「反应距离 / 制动距离 / 前方尚可用距离」画在同一根尺子上:

  =====================#####################------------------
  0                                                       40.0 m
  图例:= 反应距离(13.89 m)  # 制动距离(14.05 m)  - 前方尚可用的距离

反例

# 雨天:附着系数从 0.70 掉到 0.35,制动距离翻倍
roslaunch braking_distance_check main.launch friction:=0.35

停车距离 一条翻转:[FAIL] 停车距离 需要 41.98 m,前方可用 40.00 m(减速度只剩 3.43 m/s²,刹停要 4.05 s)。

# 跟车太近:车距 32 m → 20 m
roslaunch braking_distance_check main.launch gap:=20

跟车间距 一条翻转:[FAIL] 跟车间距 当前 20.00 m,两秒法则要求 30.78 m。

也就是说:同一次运行里,每个失败都指向一个具体的物理量,而不是笼统的「不安全」。

离线测试

cd <仓库根目录>
python3 tests/test_braking_distance_check_local.py

只用标准库,不需要 ROS、不需要 CARLA、不需要显示器;同时兼容 Python 2.7 与 3.x。期望看到:

通过 208 项,失败 0 项
全部通过

也可以交给 pytest:

python3 -m pytest tests/test_braking_distance_check_local.py -q

与已有模块的关系

模块 关注点 与本模块的区别
carla_aeb_braking CARLA 里的自动紧急制动 需要 CARLA;本模块只算物理量,不控制车辆
twist_to_control 速度指令 → 转角/轮速 算执行量;本模块算执行后要多少米停住
turning_sweep_check 转弯时车身占多宽 算横向包络;本模块算纵向距离
本模块 纵向制动距离 纯物理、纯终端输出,用于跟车与限速的合理性判断

常见问题

为什么默认车距是 32 m,不是整数 30 m? 50 km/h 下两秒法则要求 13.889 × 2 + 3 = 30.78 m,30 m 会直接判失败。把默认值放在 32 m 是为了让「默认工况通过、调小参数才失败」这个对照成立。

附着系数取多少才合理? 干沥青 0.7~0.9、湿沥青 0.4、压实雪 0.2、冰面 0.1。本模块把 μ < 0.30 直接判为不安全(雪天以下就不要谈刹停了)。

为什么制动距离用 v²/(2a) 而不是查表? 这是匀减速的解析解:v² = 2as。只要减速度恒定,结果与车型无关,所以它可以手算复核——本模块的离线测试里就有几条是手算对照的。

Melodic 上会看到 UnicodeEncodeError 吗? 不会。所有日志先编码成 byte str 再交给 rospy.loginfo(braking_node.py 的 _log())。

大模型声明

使用大模型辅助代码编写、测试编写与文档整理,提交内容由本人负责。