ARC-Humanoids-Infoys/HarcOS
GitHub: ARC-Humanoids-Infoys/HarcOS
HarcOS 是一个基于 MCP 协议的模块化机器人控制框架,为人形和四足机器人提供统一的硬件抽象和标准化 AI 工具接口。
Stars: 0 | Forks: 0
# HarcOS — 人形机器人控制系统
一个使用 Model Context Protocol (MCP) 的模块化、与硬件无关的人形机器人控制框架。HarcOS 通过标准化的技能和 CLI 命令,提供了一个统一的接口来管理多个机器人平台(Unitree Go2、Unitree G1 等)。
## 项目架构
HarcOS 基于清晰的关注点分离构建:
```
HarcOS/
├── mcp_server.py ← Shared FastMCP server factory
├── registry.py ← Robot name → blueprint mapping
├── run.py ← CLI entry point
├── robots/
│ ├── base.py ← RobotController abstract base class
│ ├── go2/
│ │ ├── controller.py ← Go2 hardware integration layer
│ │ ├── skills.py ← MCP tool registrations for Go2
│ │ └── blueprint.py ← Go2 factory function
│ └── g1/
│ ├── controller.py ← G1 hardware integration (SDK2 DDS)
│ ├── skills.py ← MCP tool registrations for G1
│ └── blueprint.py ← G1 factory function
└── requirements.txt
```
## 核心设计原则
**1. 共享 MCP 基础设施**
- `mcp_server.py` 集中管理 FastMCP 实例的创建
- 所有机器人蓝图复用相同的服务器工厂
- 单一事实来源防止重复
**2. 每个机器人的独立组合**
- `robots//blueprint.py` 组装 controller + skills + MCP server
- 返回准备好执行的 (mcp, controller) 元组
- 支持轻松更换机器人
**3. 每个机器人的独立技能注册**
- `robots//skills.py` 注册 MCP @tool 装饰器
- 每种机器人类型拥有独立的技能定义
- 可扩展设计,支持自定义功能
**4. 最小化核心技能**
- `connect` / `disconnect` — 建立/关闭机器人连接
- `get_battery` — 电池状态
- `move` / `stop` — 运动控制
- 机器人特定技能(Go2:运动指令;G1:stand_up/stand_down)
## 用法
### Go2 机器人
```
# 默认连接(Claude Desktop 的 stdio 模式)
python run.py go2
# 连接到特定 IP 地址
python run.py go2 --ip 192.168.123.161
# HTTP 服务器模式(端口 9990)
python run.py go2 --transport sse --port 9990
```
### G1 机器人
```
# 默认连接 — DDS 网络接口会自动检测
python run.py g1
# 如果自动检测选错了接口则覆盖该接口
python run.py g1 --interface enp0s31f6
# HTTP 服务器模式(端口 9991)
python run.py g1 --transport sse --port 9991
```
### MCP Inspector(调试与测试)
使用 [MCP Inspector](https://github.com/modelcontextprotocol/inspector) 交互式地探索和测试所有可用工具:
```
# 检查 Go2 机器人工具
npx @modelcontextprotocol/inspector python3 run.py go2
# 检查 G1 机器人工具
npx @modelcontextprotocol/inspector python3 run.py g1
```
这会启动一个基于浏览器的 UI,你可以在其中浏览所有已注册的 MCP 工具,手动调用它们,并检查输入/输出 —— 这对于开发和硬件调试非常有用。
## 环境变量
**Go2:**
- `ROBOT_IP` — Go2 IP 地址(默认为 192.168.123.161)
**G1:**
- `G1_ROBOT_IP` — G1 标识符/IP(可选,DDS transport 不使用)
- `G1_NETWORK_INTERFACE` — 用于 DDS 通信的网络接口。如果未设置则**自动检测**(依次尝试 `eth0` → `enp0s31f6` → `enp0s25` → `eno1` → 第一个非环回接口)。仅在自动检测选择了错误接口时进行覆盖。
## G1 技术说明
### DDS Transport 与 WebRTC 对比
| | Go2 | G1 |
|---|---|---|
| Transport | WebRTC (`unitree_webrtc_connect_leshy`) | DDS / CycloneDDS (`unitree_sdk2py`) |
| Addressing | IP 地址 | 网络接口名称 |
| Motion client | `SportClient` | `LocoClient` + `MotionSwitcherClient` |
### IDL Schema:`unitree_hg` 与 `unitree_go`
Go2 使用 `unitree_go` IDL;G1 使用 **`unitree_hg` (humanoid)** IDL。它们
在**结构上完全不同**。关键后果如下:
| 字段 | `unitree_go.LowState_` (Go2) | `unitree_hg.LowState_` (G1) |
|---|---|---|
| `bms_state` | ✅ 存在 | ❌ 不存在 |
| `power_v` / `power_a` | ✅ 存在 | ❌ 不存在 |
| `motor_state[i].vol` | ✅ 存在 | ✅ 存在 |
| `imu_state` | ✅ 存在 | ✅ 存在 |
### G1 上的 `get_battery`
由于 `unitree_hg.LowState_` 没有 BMS/电源字段,G1 上的 `get_battery()`
返回**电机电源电压**作为代理,以及一个 **占位符 SOC** (85%)。
完整的电池 SOC 需要订阅单独的 BMS DDS topic(尚未
实现)。`voltage_v` 字段(~51V)是真实的,反映了电源总线电压。
## 添加新机器人
HarcOS 的设计支持扩展。要添加 H1、H2 或任何其他机器人平台:
### 1. 创建 `robots/h1/controller.py`
```
from robots.base import RobotController
class H1Controller(RobotController):
def __init__(self, **kwargs):
# Initialize your hardware connection
pass
def connect(self) -> str:
# Establish connection to robot — return a human-readable status string
return "Connected to H1"
def disconnect(self):
# Close connection gracefully
pass
def move(self, vx: float, vy: float, omega: float) -> dict:
# Execute motion command
pass
def stop(self) -> dict:
# Stop all motion
return {"status": "stopped"}
def get_battery(self) -> dict | str:
# Return battery status dict, or error string on failure
return {"soc_percent": 100, "voltage_v": 51.0, "current_a": 0.0}
def get_pose(self) -> dict:
# Return current pose/position
return {"x": 0, "y": 0, "theta": 0}
```
### 2. 创建 `robots/h1/skills.py`
```
from fastmcp import FastMCP
from robots.base import RobotController
def register(mcp: FastMCP, controller: RobotController):
@mcp.tool()
def connect() -> str:
"""Connect to H1 robot."""
result = controller.connect()
return f"Connected: {result}"
@mcp.tool()
def get_battery() -> str:
"""Get H1 battery status."""
result = controller.get_battery()
return f"Battery: {result['battery']}%"
# Add more skills as needed
```
### 3. 创建 `robots/h1/blueprint.py`
```
from robots.h1.controller import H1Controller
from robots.h1.skills import register
from mcp_server import create_server
def build_h1():
"""Factory function to assemble H1 robot with MCP server."""
mcp = create_server("h1")
controller = H1Controller()
register(mcp, controller)
return mcp, controller
```
### 4. 更新 `registry.py`
```
from robots.h1.blueprint import build_h1
BLUEPRINTS = {
"go2": build_go2,
"g1": build_g1,
"h1": build_h1, # Add this line
}
```
**大功告成!** 现在 `python run.py h1` 将立即生效。
## 设计理念
- **最小化核心**:仅包含必要的硬件抽象
- **模块化技能**:每个机器人独立注册其功能
- **整洁接口**:`RobotController` 基类确保一致性
- **易于扩展**:无需修改现有代码即可添加新机器人
- **MCP 优先**:所有技能均作为标准化的 MCP 工具暴露给 AI agent
# HarcOS
标签:MCP, Unitree, 人形机器人, 机器人控制, 硬件抽象, 运动控制, 逆向工具