LeRobot documentation

编写文档字符串

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.7.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

编写文档字符串

LeRobot 的 API 参考文档直接由 src/lerobot/ 中的 docstring 生成。docstring 并非注释,而是该对象的正式文档,以下格式是渲染器和 CI 检查所解析的格式。

此页面即为约定。如果您要在 src/lerobot/ 中添加或编辑任何公开内容,请遵循此约定。

未记录的公开方法就是不可见的方法。 [[autodoc]] 会静默跳过没有文档字符串的成员——没有警告,没有错误,它只是不会出现在渲染后的页面上。覆盖率和 API 参考的完整性是同一个问题。

一个示例中的格式

Google 章节标题,Hugging Face 类型格式。两者兼备,而非二选一。

def send_action(self, action: RobotAction, rate_hz: float = 30.0) -> RobotAction:
    """Command the robot to move to a target joint configuration.

    Values are clipped by the configured maximum relative target before reaching the motors, so the
    returned action may differ from the requested one.

    Args:
        action (`dict[str, float]`):
            Target values keyed by motor name, e.g. `{"shoulder_pan.pos": 0.0}`. Keys must match the
            robot's action features.
        rate_hz (`float`, *optional*, defaults to `30.0`):
            Control loop frequency.

    Returns:
        `dict[str, float]`: The action actually written to the motors after safety clipping.

    Raises:
        DeviceNotConnectedError: If the robot has not been connected.

    Example:
        ```python
        >>> from lerobot.robots.so_follower import SO101Follower, SO101FollowerConfig
        >>> robot = SO101Follower(SO101FollowerConfig(port="/dev/ttyACM0"))  # doctest: +SKIP
        >>> robot.connect()  # doctest: +SKIP
        >>> robot.send_action({"shoulder_pan.pos": 0.0})  # doctest: +SKIP
        ```
    """

本页示例中省略了交叉引用——有关其语法以及为何无法在代码块中显示的原因,请参阅交叉引用。

规则

章节

Args: · Returns: · Raises: · Yields: · Example: · Note:

按此顺序。不要使用其他章节标题。首先是一行摘要,然后是可选的自由格式描述,最后是各个章节。

Args: 行会被机器解析

name (`type`, *optional*, defaults to `X`):
    Description, indented on its own line.

The *optional*, defaults to clause is checked against the real signature default by make check-docstrings. It is not decorative — if you write a default that has drifted from the code, CI fails. Omit the clause entirely for required parameters:

    Args:
        port (`str`):
            Serial port the arm is connected to, e.g. `/dev/ttyACM0`.
        max_relative_target (`float | dict[str, float]`, *optional*):
            Caps the magnitude of the relative positional target vector. `None` disables clipping.
        use_degrees (`bool`, *optional*, defaults to `True`):
            Keep `True` for backward compatibility with existing policies and datasets.

类型应使用反引号。当默认值为 None 或无需重复说明时,请使用 *optional*,而不使用 defaults to。

返回:类型优先

缩进一行的格式,先输入类型,然后输入冒号,最后输入描述:

    Returns:
        `dict[str, float]`: The action actually written to the motors after safety clipping.

Yields: 形状相同。

**属性**:, 永不 属性:

doc-builder 会将单独的 Attributes: 解析为 Parameters: 的同义词,因此您的属性会被渲染为构造函数参数。这种处理是静默的且错误的。只要属性与构造函数参数不同,请使用带有 -- 分隔符的粗体形式:

class Robot(abc.ABC):
    """The base abstract class for all LeRobot-compatible robots.

    **Attributes**:
        - **config_class** (`type[RobotConfig]`) -- The expected configuration class for this robot.
        - **name** (`str`) -- The unique robot name used to identify this robot type.
    """

注意 --,而不是 :。

交叉引用

使用 doc-builder 的括号语法:用方括号括起来的反引号路径。不支持 Sphinx 角色(:pymeth:、:pyattr:),它们会在页面上以纯文本形式显示。

想要写入
主包中的类[Robot]
方法,显示完整路径[Robot.connect]
方法,显示裸名称[~Robot.connect]
嵌套路径[~robots.Robot.connect]
另一个 HF 库中的对象[~accelerate.Accelerator]

~ 仅从 链接文本 中去除路径;链接仍会解析为完整路径。

doc-builder 会在页面的所有位置解析此语法——包括围栏代码块内部。这就是为什么本页上的 docstring 示例使用普通文本而非交叉引用:包含交叉引用的代码块会渲染出解析后的链接,而不是你需要输入的语法。在你自己的 docstring 中,请随意使用交叉引用;此限制仅影响关于该语法的文档 about。

提示

使用 GitHub 风格的引用块:

> [!TIP]
> Call this once at startup — it takes about two seconds.

> [!WARNING]
> Torque is disabled on disconnect. The arm will drop if it is holding a load.

<Tip> 组件在 doc-builder 中属于遗留组件;请勿再添加新的此类组件。

示例必须使用围栏

示例位于一个包含 >>> 的围栏式 ```python 代码块中。正是这个围栏使其渲染为代码块,也是 doctest 预处理器正则表达式所查找的内容:

    Example:
        ```python
        >>> from lerobot.robots.so_follower import SO101FollowerConfig
        >>> cfg = SO101FollowerConfig(port="/dev/ttyACM0")
        >>> cfg.use_degrees
        True
        ```

未加围栏的 >>> 仍会被收集——doctest 会在 docstring 的任何位置查找提示符。你失去的是渲染效果,因此它在页面上会显示为一整段文字。每个示例都需要围栏。

每个示例要么在 CI 中执行,要么带有 # doctest: +SKIP。任何涉及硬件、GPU 或从 Hub 下载内容的示例都会添加 +SKIP:

    Example:
        ```python
        >>> robot.connect()  # doctest: +SKIP
        >>> policy = ACTPolicy.from_pretrained("lerobot/act_aloha_sim_transfer_cube_human")  # doctest: +SKIP
        ```

将包含可运行示例的文件添加到 utils/documentation_tests.txt 中。

将示例放在模块的三个到五个真正的入口点上。在琐碎的访问器上放置示例只会带来噪音。

你会经常遇到的三种模式

配置数据类

配置字段在历史上是通过每个字段上方的 # 注释来记录的。doc-builder 无法识别行内注释——这样的类在渲染时会列出所有字段,但没有任何描述。请将它们移到类文档字符串中的 Args: 块中:

@dataclass
class SOFollowerConfig:
    """Configuration for SO-family follower arms.

    Args:
        port (`str`):
            Serial port the arm is connected to, e.g. `/dev/ttyACM0`.
        max_relative_target (`float | dict[str, float]`, *optional*):
            Caps the magnitude of the relative positional target vector. A scalar applies to all motors;
            a dict maps motor name to a per-motor cap. `None` disables clipping.
        use_degrees (`bool`, *optional*, defaults to `True`):
            Keep `True` for backward compatibility with existing policies and datasets.
    """

    port: str
    max_relative_target: float | dict[str, float] | None = None
    use_degrees: bool = True

doc-builder 不会从基类继承 docstring。LeRobot 中注册的配置类通常是薄弱的多重继承垫片:

@RobotConfig.register_subclass("so101_follower")
@dataclass
class SOFollowerRobotConfig(RobotConfig, SOFollowerConfig):
    pass

该类会渲染所有字段——包括继承的字段——且完全不带任何描述,无论基类的文档写得多么完善。Args: 块必须位于 [[autodoc]] 所指定的具体类中,并且必须涵盖继承的字段。

基类,然后是具体的子类

抽象基类承载了规范契约。子类只需记录偏离之处——端口语义、校准特性、电机布局、支持的功能键。切勿将基类契约复制到每个子类中。

Robot、Teleoperator、Camera、MotorsBusBase、ProcessorStep 和 PreTrainedPolicy 都遵循此结构。

模块级别名

多个公开名称是别名,而非独立的类:

SO100FollowerConfig = SOFollowerRobotConfig
SO101FollowerConfig = SOFollowerRobotConfig

[[autodoc]] 会解析别名并渲染规范类名,因此 ## SO101FollowerConfig 标题下的正文将显示 class lerobot.robots.so_follower.SOFollowerRobotConfig。只需为规范类编写一次文档,并在页面正文中提及别名,而不是为每个别名单独创建 autodoc 块。

不应记录的内容

  • 私有成员。 以 _ 开头的任何内容都不属于公共 API。
  • 以文字形式重述的类型注解。 port (str): A string. 没有提供任何信息。请说明它的用途。
  • 来自上游的内置代码。 src/lerobot/policies/molmoact2/molmoact2_hf_model/ 是从 transformers 内置的,并且已经带有上游风格的文档字符串。请保持原样——重新调整其格式只会导致下次同步时产生冲突。它已被排除在 API 参考和文档字符串检查之外。

此规则如何强制执行

检查它能捕获的内容
make check-docstringsArgs: 条目与签名不匹配;文档中记录的默认值与实际值不一致
make doctest不再运行的示例
make check-doctest-listutils/documentation_tests.txt 中的过期或未排序条目
ruff(D 规则)Google 规范风格的违规
interrogateDocstring 覆盖率低于当前阈值
doc-builder指向不存在内容的 [[autodoc]] 路径——这会导致文档构建失败

在提交 PR 之前,请一起运行它们:

make check-docstrings && make doctest && pre-commit run --all-files

然后渲染页面并实际查看它:

doc-builder build lerobot docs/source/ --build_dir /tmp/doc-build

检查清单

  • 您修改过的每个公共成员都有文档字符串。
  • 每个 Args: 条目都与签名匹配,包括 *optional*, defaults to 子句。
  • Returns: 采用类型优先,缩进一行。
  • 不要使用裸的 Attributes: — 请使用 **Attributes**: 并配合 -- 分隔符。
  • 没有 Sphinx 角色 — 交叉引用使用 [~module.Class.method]。
  • 示例位于 ```python 围栏代码块中,并且要么在 CI 中运行,要么带有 # doctest: +SKIP。
  • Config 数据类字段位于具体类的 Args: 块中,而不是 # 注释。
  • 已目视检查渲染后的页面。
Update on GitHub