机器人如何交流:使用 gRPC 和 WebRTC 构建分布式机器人
如果您正在构建任何类型的分布式机器,例如机器人、无人机或物联网设备,以下两个问题很快就会浮现出来
- 如何高效地发送结构化命令和数据?
- 当网络不可靠时,如何保持通信的弹性?
在本文中,我将分享我们在 Viam(一个结合 gRPC 用于结构化 RPC 和 WebRTC 用于点对点流媒体的开源机器人平台)所使用的方法。即使您不是在构建机器人,相同的架构思想也可以帮助您设计更具可扩展性和适应性的系统。
弥合实验室级机器人技术与实际系统之间的鸿沟
ROS(机器人操作系统)长期以来一直是构建和原型化机器人系统(特别是在研究和学术领域)的首选框架。它在受信任的本地网络上运行良好,因为这就是它的设计初衷。
但如今的机器人不再局限于严格受控的实验室工作台。它们被部署在工厂车间、海上或偏远地区,这些地方的网络条件不可预测,可靠性至关重要。
ROS 本身不处理网络通信。如果您需要通过互联网与机器人通信,则需要自行设计解决方案。现代机器人技术需要的不仅仅是本地局域网协议。它需要支持云、点对点且具有弹性的通信堆栈。
Viam 没有依赖像 MQTT 这样的分布式消息堆栈或通过云中继命令,而是使用 gRPC 和 WebRTC 来支持 其机器人平台。这些协议协同使用,提供了一种现代替代方案,补充了 ROS 的优势。gRPC 提供结构化、语言无关的 API,并具有快速、高效的 Protobuf 序列化功能。WebRTC 则增加了低延迟的点对点连接,这对于在机器之间传输传感器数据或实时视频非常理想。
一些机器人开发者也在 ROS 之上叠加 gRPC 接口,将 ROS 丰富的生态系统与 gRPC 的现代传输和可扩展性融为一体。
为什么 gRPC 对机器人有意义
现代机器人不再是固定环境中的单一用途机器。它们是移动的、多组件的系统,需要与传感器、感知服务和控制回路协同工作,通常是实时工作。
gRPC 通过以下几个关键方式支持这些需求
- 低延迟、实时控制:gRPC 支持连续、双向的流,允许系统向机械臂发送实时姿态更新,同时接收遥测数据,而无需额外的往返延迟。
- 跨平台、多语言一致性:gRPC 自动为 Python、Go、C++ 等语言生成客户端库(存根),从而更轻松地以一致的接口连接不同的设备、SDK 和环境。
- 轻量级和高效序列化:gRPC 在带宽受限环境或嵌入式设备中也很有帮助,这得益于 Protobuf 的轻量级二进制编码。
- 安全优势:gRPC 在设计时就内置了端到端加密(默认使用 TLS)和认证功能,确保机器部件之间(无论是通过本地网络还是公共互联网)的安全通信,而无需开发人员额外添加安全层。
- 机器部件的服务抽象:通过 gRPC 和 Protobuf,机器人的每个部件,从电机到摄像头再到传感器,都可以被建模为标准化的、语言无关的服务。
在 Viam 的公共 API 中,每个机器人组件都使用 Protobuf 定义为 gRPC 服务。机械臂、摄像头和传感器等组件暴露了类型化的方法,可以远程调用。以下是摘自 arm.proto
文件的摘录,该文件定义了机械臂的基本移动和姿态检索方法
// An ArmService services all arms associated with a robot
service ArmService {
rpc MoveToPosition (MoveToPositionRequest) returns (MoveToPositionResponse);
rpc GetEndPosition (GetEndPositionRequest) returns (GetEndPositionResponse);
rpc GetJointPositions(GetJointPositionsRequest) returns (GetJointPositionsResponse);
}
这些 proto 服务可以生成 SDK 来帮助您操作机器。此示例使用 Python SDK 来移动机械臂。在底层,gRPC 负责将命令编码为 Protobuf 消息,并通过 HTTP/2(或 WebRTC,取决于环境)发送。
from viam.components.arm import ArmClient
arm = ArmClient.from_robot(robot=robot, name="my-arm")
# Move the arm to a target 3D position
arm.move_to_position(x=0.1, y=0.2, z=0.3, orientation=None, world_state=None)
为什么 WebRTC 也是其中一部分
乍一看,gRPC 和 WebRTC 可能显得多余。两者都可以流式传输数据并发送结构化消息。但它们解决了机器人领域中截然不同的挑战。
WebRTC 擅长建立直接的点对点连接,这在以下情况下至关重要:
- 设备位于本地网络或受 NAT/防火墙限制时
- 您想绕过中央中继或云服务器时
- 您在机器之间传输高带宽传感器数据(如实时视频或 LIDAR)时
Viam 使用 gRPC 进行编排,WebRTC 作为底层传输协议,将两者结合起来,以实现快速、结构化的消息传递,并最大程度地减少路由开销。
使用 gRPC 实现灵活的传输层
虽然 WebRTC 支持分布式机器中的点对点通信,但 gRPC 也提供了灵活地更换底层传输层的能力。
这里有一个 运行在 WebRTC 和其他传输协议之上的 gRPC 服务器示例。Viam 还使用 Unix 域套接字 (UDS) 在 viam-server
和内部模块之间进行本地消息传递;使用蓝牙进行机器配置或代理网络流量;以及使用串口连接嵌入式外设。
由于 gRPC 在 API 层定义了一致的接口,我们可以根据环境或设备更改传输协议,而无需重写客户端逻辑,这在构建跨云、本地和受限网络的系统时是一个巨大的优势。
一个真实世界的例子:协调抓娃娃机
想象一下一台遥控抓娃娃机,就像您在街机厅看到的那种。它有两个主要组件:一个摄像头和一个机械臂。用户界面,例如 网络应用 或 移动应用,发送控制命令并接收实时视频流,以帮助引导爪子抓取奖品。


以下是 gRPC 和 WebRTC 在幕后协同工作的方式
- 初始化:系统通过 HTTP/2 使用 gRPC 建立控制通道。每个组件注册其服务(例如
ArmService
,CameraService
)。 - 连接:gRPC 协调对等元数据和信令的交换,以在 SDK 和机器部件之间建立 WebRTC 会话。
- 实时操作:WebRTC 现在直接在对等方之间处理媒体和数据流。命令使用 gRPC 方法调用发送,通过 WebRTC 传输路由。视频和传感器流则反向流动。


这种双协议方法即使在不可预测的网络条件下,也能实现实时交互、流畅的流媒体传输和弹性回退行为。
为什么这种模式对更广泛的社区很重要
gRPC 的结构和 WebRTC 的灵活性相结合,为新型分布式系统打开了大门,不仅限于机器人领域,还适用于任何需要以下特性的场景:
- 松散耦合系统之间的实时双向通信
- 跨语言和设备的类型化、版本化 API
- 传输无关的灵活性,并在需要时可选择点对点通信
gRPC 组织对话。WebRTC 在网络中传输它。
Viam 实现实时机器人控制
gRPC 已经远远超出了简单的请求/响应 API。在机器人以外的许多行业中,机器之间的通信方式比以往任何时候都更加关键。gRPC 和 WebRTC 不仅仅是更快的协议,它们更是下一代分布式、弹性化和智能机器的重要构建模块。
如果您正在构建需要在设备、环境和网络之间相互通信的系统,那么是时候探索一个更具可扩展性和适应性的通信层了。
虽然您可以自行构建类似的堆栈,但 Viam 开箱即用地提供了这些功能。其机器上的功能是开源且免费使用的,当您扩展到机群时,还可以根据使用情况选择云服务。
技术审阅人:Nick Hehr (Viam)