摘要
上一篇文章 “别把 Foxglove 当权限系统:ROS 2 可视化平台最容易踩的一个坑” 先把一个最容易踩的坑说清楚了:别把 Foxglove 当权限系统。
这个判断说清以后,后面真正要落地的,其实就剩两件事:
- 权限到底该分几层
- 哪些接口可以给
Foxglove,哪些接口不要直接给
所以这一篇不再重复上一篇那套判断过程,直接往下讲:架构怎么拆,角色怎么压,接口边界怎么收。
如果你的项目已经进入远程调试、多人协作、客户演示或者上线运维阶段,这两件事最好早点定下来。很多系统不是完全不能用,而是控制面和观测面一开始就没分开,后面越补越乱。
一、职责拆分
Foxglove + ROS 2 这套东西里,最容易混在一起的,通常是下面 4 件事:
- 谁能接进来
- 接进来以后能碰哪些 ROS 接口
- 节点之间到底有没有硬权限边界
- 当前这个动作在业务上该不该执行
这 4 件事如果全压在一层上,最后大多会变成:
- 前端在做显隐
foxglove_bridge在做一点收口- 底层接口还是直接暴露着
更稳的做法,是先把这些问题各归各位,别继续混着处理。
二、四层分工
1. 接入层
这一层只回答一件事:谁能进。
它通常关心这些事:
- 用户是否登录
- 属于哪个角色
- 能访问哪台机器人
- 是否来自允许的网络
- 是否要走
HTTPS / WSS - 是否记录访问审计
这一层一般落在:
Nginx / OpenRestyJWT / SessionOIDC / OAuth2- VPN 或零信任入口
这里重点不在 ROS 2,而在统一接入。
如果 Foxglove 直接裸暴露到外面,后面再补角色、审计和来源控制,基本都会很别扭。
2. Bridge 层
这一层只负责一件事:桥接层收口。
也就是决定 ROS 2 这一侧哪些内容可以被桥到 WebSocket,例如:
topic_whitelistservice_whitelistparam_whitelistclient_topic_whitelistcapabilitiesaddresstlsasset_uri_allowlist
这一层该做的,是先把暴露面收紧,不是自己去扛完整权限系统。
工程上更实用的做法就三条:
- 默认最小暴露
- 默认只读优先
- 不把危险底层接口直接桥出去
3. ROS 2 安全层
这一层回答的是:节点本身有没有权访问。
如果项目后面要交付、远程运维或者长期上线,那单靠前端显隐和 bridge 白名单通常不够,还是得回到 SROS2 / DDS Security 这一层来兜底。
它解决的是这类问题:
foxglove_bridge所在节点能不能访问某些 Topic- UI 代理节点能不能调某些 Service
- 核心控制节点是否只接受受控节点的访问
- 某个部署单元是否持有不该持有的安全制品
说白一点,就是上层即使配错了,底层也不能默认裸着。
4. 业务代理层
这一层最容易被低估,但其实最关键。
因为很多动作就算接口上允许,也不代表当前就该执行,比如:
- 启动任务
- 暂停任务
- 恢复任务
- 取消任务
- 手动点动
- 设置初始位姿
- 故障恢复
这些动作通常还要看:
- 当前是不是自动模式
- 任务是否正在运行
- 是否存在故障锁
- 是否满足互锁条件
- 是否需要二次确认
- 是否需要审计留痕
所以更稳的做法,不是让 Foxglove 直接碰底层,而是只让它调用高层业务接口。真正执不执行,由代理节点判断。
三、角色划分
很多项目一上来就想把 RBAC 做得很细,结果菜单权限、接口权限、节点权限和业务状态全缠到一起。
更实用的起点,通常是先压成 3 类。
1. Viewer
这一类就进观测面。
通常允许:
- 看地图、
TF、视频 - 看点云、激光
- 看诊断信息
- 看运行状态
- 看日志趋势
通常不允许:
- 主动
publish - 调
service - 改
parameter - 执行控制动作
如果场景是看板、客户演示、远程观察,这一类角色往往最省心,因为它根本不进控制面。
2. Operator
这是最常见的业务角色。
通常允许:
- 启动任务
- 暂停任务
- 恢复任务
- 取消任务
- 下发高层目标
- 做有限手动点动
但这里关键不在“给不给控制”,而在:
只能碰高层业务接口,不能直通底层接口。
也就是说,给它的是:
/ui/start_task/ui/pause_task/ui/resume_task/ui/cancel_task/ui/manual_jog/ui/set_initial_pose
而不是:
/cmd_vel- 原始电机使能
- 原始设备控制
- 底层驱动
service
3. Admin
这一层不是让管理员永久常驻最高权限,而是给维护、恢复、校准这些场景做短时放权。
通常允许:
- 调诊断类
service - 读写有限参数
- 执行恢复类操作
- 查看更完整的内部状态
但最好同时带上:
- 审计日志
- 权限过期
- 二次确认
- 与普通操作角色隔离
很多系统最后边界失守,不是因为完全没做权限,而是管理员权限长期常开。
四、接口划分
真到落地的时候,最值得单独整理的,往往不是角色表,而是接口清单。
1. 适合直接暴露给 Foxglove 的
这类接口主要承担观测作用,通常可以直接进 bridge 白名单:
/tf/tf_static/map/odom/scan/pointcloud/camera/*/diagnostics/robot_status/battery_state
它们有个共同点:主要用于可视化、诊断和观测,不直接进入危险控制链路。
2. 适合暴露给前端,但要经过代理层的
这类接口可以给操作角色,但建议都先收口成高层业务入口:
/ui/start_task/ui/pause_task/ui/resume_task/ui/cancel_task/ui/manual_jog/ui/set_initial_pose
这样做的好处很直接:
- 语义清晰
- 便于做状态校验
- 便于做角色区分
- 便于做审计
- 后续扩展成本低
3. 不建议直接暴露给 Foxglove 的
这类接口建议默认按高风险处理。
底盘原始控制
/cmd_vel- 原始速度命令
- 电机使能 / 失能
- 控制器底层
service
设备原始执行
- 叉齿原始升降控制
- 液压原始控制
- 原始继电器输出
- 原始 I/O 输出
总线与驱动透传
- CAN 原始透传
- 串口透传
- 驱动层调试
service
核心参数直改
- 核心 PID
- 安全阈值
- 控制模式参数
- 关键定位参数
很多风险不是来自那些一眼就很危险的接口,而是来自调试阶段顺手开出来、后面一直没收回去的接口。
这类接口一旦给前端直通,Foxglove 在事实上就已经进控制面了。
五、推荐链路
很多项目早期是这样接的:
它能跑,但问题也很明显:
- 前端直接碰底层
- bridge 事实上成了控制面
- 角色边界和业务边界混在一起
- 很难做审计
- 很难做状态互锁
上一篇已经给过一张总览图:认证网关 -> foxglove_bridge -> UI代理节点 -> 核心 ROS 2 节点。
把那张总览图往下展开,尤其是把 bridge 后面到底接什么、UI 代理节点内部再怎么分,链路更接近下面这种:
这套结构里,每一层干的事都比较清楚:
- 认证网关决定谁能进
foxglove_bridge决定桥接层暴露什么- UI 代理节点决定当前动作是否允许执行
- 核心 ROS 2 节点只接受受控调用
SROS2 / DDS Security继续提供节点级硬边界
六、落地顺序
如果你现在项目里已经用了 Foxglove,但权限边界还比较粗,建议按这个顺序往回收:
- 先把
foxglove_bridge从“默认全开”改成“默认从严”。 - 先分开观测接口和控制接口,不要继续混在一个暴露面里。
- 不要再让前端直接碰
/cmd_vel、原始控制service和核心参数写接口。 - 把高风险动作改成经过业务代理节点,由状态机、互锁和审计去兜底。
- 再规划
SROS2 / DDS Security,把节点级硬权限补上。 - 如果需要远程接入,把监听地址、网络边界和
TLS / WSS一起收紧。
这几步不一定一次做完,但顺序最好别反。
先收 bridge 暴露面,再收业务入口,再补节点级硬边界,这样返工最少。
七、小结
上一篇解决的是“别放错位置”,这一篇解决的是“放对以后怎么收”。
核心其实就这 4 句:
- 接入层解决谁能进
- bridge 层解决暴露什么
- ROS 2 安全层解决节点本身有没有权访问
- 业务代理层解决当前动作该不该执行
如果再压成一句话,就是:
Foxglove适合做观测入口和桥接收口,不适合直接进入底层控制面。
如果你现在的系统还是“登录后直接进 Foxglove,按钮显隐当权限,底层接口顺手桥出去”,那它大概率还停留在能跑阶段,离适合上线还差一截。
下一篇我会继续往下走,不再停留在分层判断,而是直接进实战,重点会放在这几件事上:
foxglove_bridge的配置原则怎么定- 节点分层到底怎么落
- 高风险动作怎么做代理
- 哪些接口该桥,哪些接口该隔离
评论区