依据:/home/osrbot/osracer_ws/src/osracer_base(底盘驱动)与
/home/osrbot/osracer_ws/src/osracer(整车与 osracer_race 控制器框架)。
本页把仿真训练出的策略与实车接口逐项对照,指出缺口、风险与分阶段上线步骤。
参考实现放在 deploy/osracer_policy/,可直接拷入车辆工作区构建。
| 项 | 实际配置 | 对策略的含义 |
|---|---|---|
| 驱动 | 单电机四驱 | 四轮机械耦合,只有一个速度自由度;仿真里用于漂移的后轮增速没有执行器,软件无法补 |
| 测速 | 单编码器(由它算出 odom) | 只有整车/传动链速度,没有逐轮转速 |
| 转向 | 总线数字舵机,无角度反馈 | 只有指令,没有实测转角 |
| 转向机构 | 单拉杆 + 倒梯形(阿克曼)连杆 | 舵机角到左右轮角是非线性、且左右不等的映射;策略输入需要的是"当前实际轮角" |
| 控制形式 | 开环 | 执行器滞后、回差、连杆间隙都不在观测里 |
因此观测契约里 wheel_vel[4] 与 steer_pos[2] 需要按下表降级,而不是当作已有:
| 策略输入 | 实车可得 | 判定 |
|---|---|---|
wheel_vel[4] |
单编码器速度 → 四轮同值 | 可以接受:单电机四驱本就是一个自由度,策略内部也只用前轮均值投影前进速度 |
steer_pos[2] |
仅舵机指令(无实测角) | 需要处理:策略有三处用到它(投影编码器速度、漂移触发、安全层前瞻包络)。直接喂指令等于假设车轮已在指令位置,舵机运动过程中该假设不成立 |
| 后轮增速(漂移) | 不存在 | 必须降级:把 rear_overdrive_ratio 设为 0,仿真里这等价于精确回退到基线动作路径 |
| 方向 | 接口 | 说明 |
|---|---|---|
| 指令 | cmd_vel(geometry_msgs/Twist) |
内部换算成 speed + atan(wheelbase*ω/v) |
| 指令 | ackermann_cmd(ackermann_msgs/AckermannDrive) |
直接下发 speed(m/s) 与 steering_angle(rad) |
| 串口协议 | v <speed_mps> <steering_deg> |
460800 baud,cmd_timeout=0.5 s 超时自动停车 |
| 反馈 | odom(nav_msgs/Odometry)、imu/data、rc_data、magnetometer_data、battery_state、TF odom→base_footprint |
只有整车线速度,没有逐轮转速、没有转向关节角 |
| 能力协商 | 连接时 vehicle get 返回 WheelbaseMm、ForwardMaxMmps、ReverseMaxMmps、SteeringMaxMdeg |
限幅由驱动内部完成,单位换算后生效 |
| 失效保护 | 固件校验失败即不使能运动;遥控接管时忽略 ROS 指令 | 已有,保留 |
s 遥测帧有 18 个字段:px,py,pz, vx,vy,vz, [6], qx,qy,qz,qw, ax,ay,az, gx,gy,gz。
驱动当前未使用第 7 个字段(索引 6)。上线前需要确认它是否为偏航角速度或转向角——
若是转向角,就能把策略输入里的“转向关节角”从“上一次指令”升级为实测值。
| 环节 | 节点 | 话题 |
|---|---|---|
| 激光 | lakibeam1(LakiBeam 1,2D) |
/scan,frame laser,默认 30 Hz、scan_range_start/stop = 45°/315°(即 270° 视场) |
| 定位 | 底盘 odom + IMU 经 EKF |
/odometry/filtered |
| 控制器 | gap_follow_node / pure_pursuit_node / mpc_controller_node / stanley_node |
发 /race/raw_ackermann_cmd |
| 安全 | safety_node |
发 /race/safety_stop(遮挡、FOV 无有效点、激光超时都会置位) |
| 限幅 | speed_profile_node |
最终限幅后发 /ackermann_cmd |
| 计时/评估 | lap_timer_node、race_evaluator_node |
订阅 /odometry/filtered |
接入点因此很明确:把策略做成一个发 /race/raw_ackermann_cmd 的控制器节点,
让既有 safety_node 与 speed_profile_node 继续工作,不绕开任何一层。
| 策略输入(仿真契约) | 实车来源 | 处理方式 | 缺口 |
|---|---|---|---|
wheel_vel[4](rad/s,长度 4) |
/odometry/filtered → twist.linear.x |
复现为四轮同值 v/RW |
没有逐轮编码器;后轮增速(漂移用)不可观测 |
steer_pos[2](rad,长度 2) |
无关节反馈 | 用本节点上一次下发的转向角 | 有执行器滞后与回差;待确认 s 帧索引 6 |
lidar(361 束 / 270° / 0.04–15 m / frame laser) |
/scan(LakiBeam 1,270°,30 Hz) |
重采样到 361 束;inf/NaN/超量程标为无效 |
分辨率与量程需实测;30 Hz 优于仿真的 15 Hz |
| 控制周期 | 60 Hz(仿真) | 节点在每帧 /scan 上重规划,指令按固定周期下发 |
串口与 speed_profile_node 的实际链路时延需实测 |
| 策略输出 | 实车指令 | 换算 |
|---|---|---|
| 四轮目标角速度(rad/s,统一符号) | AckermannDrive.speed(m/s,单一值) |
取前轮平均 × RW 作为整车目标速度 |
| 两个前轮转角(rad) | AckermannDrive.steering_angle(rad) |
取两者平均 |
重要限制:真值接口只支持“一个速度 + 一个转向角”,仿真里用于漂移的后轮增速
(rear_overdrive_ratio)在实车上没有对应执行器。因此冻结策略在实车上应以
“高频走廊跟踪 + 制动/脱困”能力为主,漂移段会退化为不增速的常规转向。
如果要保留漂移能力,需要固件支持左右后轮差速指令,这属于固件侧改动。
- 仿真赛道是 0.05 倍 RC 尺度、统一 1.5 m 路宽;实车赛道宽度与曲率不同。
策略参数(巡航 7.25 m/s、横向加速度 5.5 m/s²、制动 5 m/s²)是按仿真尺度标定的,
不能直接照搬到实车:
speed_profile_node的限速应作为第一道硬上限。 - 仿真轮胎是 OSRACER 的解析/原生接触模型,实车轮胎、地面与悬架不同; 侧滑与漂移的边界会在实车上显著偏移。
- 仿真激光是共享解析射线模型(含地面、有限高度墙、桥面);实车 LakiBeam 1 有 自己的量程、噪声、丢束与安装俯仰。观测契约一致,数值分布不一致。
- 仿真里没有 IMU/编码器噪声、没有串口时延;这些在实车上都存在。
结论:把这套策略当作“结构可用的控制器”,而不是“已标定好的实车调参结果”。 上线流程必须逐级验证,不能直接放开速度。
| 阶段 | 做什么 | 通过条件 |
|---|---|---|
| 0. 离线回放 | 录制实车 /scan + /odometry/filtered rosbag,节点以 shadow_mode 运行,只算不发 |
观测重采样后与仿真契约同形;指令与 gap_follow_node 同量级且无跳变 |
| 1. 台架 | 车轮离地,speed_profile_node 限速 0.5 m/s,人工持急停 |
转向方向、速度符号、限幅、/race/safety_stop 联锁全部正确 |
| 2. 低速场地 | 限速 1.0–1.5 m/s,仅走廊跟踪,禁用漂移参数 | 连续 10 圈无碰撞、无出界;与 gap_follow_node 对比不更差 |
| 3. 提速 | 逐级提高限速(2 → 3 → 4 m/s),每级重复阶段 2 | 每级都有录像与圈速记录,失败即回退一级 |
| 4. 对抗 | 引入第二辆车,启用 obstacle_overtake 类逻辑 |
超车次数、碰撞次数与仿真对照 |
| 5. 漂移 | 仅在固件支持后轮差速后再启用 | 侧滑估计与实车一致,且有独立安全阈值 |
每一级都要保留 rosbag、节点日志与圈速记录,便于对照仿真证据。
| 风险 | 影响 | 缓解 |
|---|---|---|
| 没有逐轮转速与转向反馈 | 策略输入是估计值,不是实测值 | 用 EKF 速度 + 上次指令;确认 s 帧索引 6;必要时加装转向电位计 |
| 后轮增速无执行器 | 漂移能力不可用 | 实车先禁用漂移参数;固件支持差速后再开 |
| 参数按 RC 尺度标定 | 直接照搬会超速 | 由 speed_profile_node 硬限幅,逐级提速 |
| 激光安装与仿真不同 | 走廊估计偏差 | 用实车 rosbag 重放校验观测重采样 |
| 串口 0.5 s 超时 | 指令中断即停车 | 节点以 ≥10 Hz 下发;失联即停属预期行为 |
| 策略源码漂移 | 检查点与实车代码不一致 | 节点启动时校验 actor_source_sha256,不匹配拒绝发指令 |
deploy/osracer_policy/ 是一个 ament_python 包,可直接拷入
/home/osrbot/osracer_ws/src/ 后 colcon build:
osracer_policy/mapping.py:纯函数,把LaserScan/Odometry转成策略观测, 并把策略动作转成AckermannDrive(无 ROS 依赖,便于离线测试)。osracer_policy/policy_node.py:ROS 2 节点。订阅/scan、/odometry/filtered、/race/safety_stop,发/race/raw_ackermann_cmd;支持shadow_mode(只算不发)、 限幅、失联停车与检查点哈希校验。osracer_policy/checkpoint.py:加载冻结检查点并构建 actor,校验源码哈希。
节点默认参数面向阶段 0/1:shadow_mode=true、max_speed_mps=1.0、max_steering_rad=0.3。
安装与运行命令见 deploy/osracer_policy/README.md。
| 检查 | 结果 |
|---|---|
映射与检查点单元测试(tests/test_deploy_mapping.py) |
5 项通过:扫描重采样到 361×270°、无效束归零并标无效、里程计→四轮角速度、动作→Ackermann(含限幅)、冻结检查点经部署加载器校验通过、篡改哈希被拒绝 |
| 包结构 | colcon list 在 /opt/ros/jazzy 下识别为 osracer_policy (ros.ament_python) |
| 节点模块 | 在 ROS 2 Jazzy 下导入成功(ackermann_msgs 用 stub 顶替,车辆端为既有依赖) |
| 字节编译 | python -m compileall 通过 |
尚未验证:在真实车辆上构建(本机缺 ackermann_msgs)、以及任何实车运行。这些属于阶段 0 之后的动作。
为回答"这样的观测是否可以",在仿真里加了 --observation-profile real(racing/real_vehicle.py):
单编码器速度复现为四轮同值、转向用一阶滞后舵机模型估计(τ=0.08 s、速率限 3.5 rad/s)而不是关节实测、
并把 rear_overdrive_ratio 设为 0。用冻结检查点在同一批 MuJoCo 赛道上对比:
| 赛道 | 仿真观测(冻结基准) | 实车观测配置 | 差异 |
|---|---|---|---|
| Bahrain | 50.65 s,5.325 m/s,超车 1 | 50.60 s,5.330 m/s,超车 1 | −0.05 s |
| Singapore | 48.40 s,5.057 m/s,超车 1 | 48.33 s,5.063 m/s,超车 1 | −0.07 s |
两条赛道都保持有效完圈与有效超车,单圈差异在 0.07 s 以内;连续漂移为 0(该配置已无后轮增速, 而这两条赛道的基准漂移本来也只有 0.0 s 与 0.05 s)。
边界:这是 2 条赛道的初步结果,且是在仿真里模拟实车观测,不等于实车表现;
--observation-profile 是本轮新增能力,尚未进入冻结证据链(默认仍为 sim,不影响已有 174 个回合)。
问题:单电机四驱只有"一个速度 + 一个转向角",能否做出漂移?
做法:用仓库里保留的旧冻结工作区(v9 安全层,漂移尚未被近场通道掐掉),
把 rear_overdrive_ratio 从 3.5 改为 0,在当年真正产生过漂移的赛道上跑 A/B。
| 赛道 | 后轮增速 3.5 | 后轮增速 0 | 判定 |
|---|---|---|---|
| Interlagos | 有效圈,漂移 0.133 s,最大侧滑 27.0° | 有效圈,漂移 0.0 s,最大侧滑 4.36° | 漂移完全来自后轮增速 |
| Austin | 碰撞,漂移 0.0 s,侧滑 3.8° | 碰撞,漂移 0.0 s,侧滑 3.8°(逐位相同) | 该回合增速未触发,无信息 |
结论:在这套策略的行驶方式与速度区间(后轮增速触发条件本身就是 1.2–2.55 m/s 的低速发卡弯技巧)下, 四轮同驱 + 转向只能产生约 4° 侧滑,距离漂移判据的 20° 差得很远;漂移 100% 由后轮增速贡献。 因此对这台实车而言,"没有后轮增速"等价于"没有这套策略学过的漂移机制"。
边界:仿真为 RC 尺度 NEURACER 轮胎模型;本实验检验的是当前策略的驾驶方式, 不等于"任何策略在任何速度下都无法让这台车甩尾"——例如专门用制动重心转移、更高入弯速度、 或低附着路面训练的驾驶行为是另一回事,但那需要重新训练,且实车只有整车制动、没有独立后轮制动。