Initial commit

This commit is contained in:
Junhan Chang
2025-04-17 15:19:47 +08:00
parent a47a3f5c3a
commit c78ac482d8
262 changed files with 39871 additions and 0 deletions

205
docs/conf.py Normal file
View File

@@ -0,0 +1,205 @@
# Configuration file for the Sphinx documentation builder.
# Sphinx 文档生成器的配置文件
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
import os
import sys
# 将项目的根目录添加到 sys.path 中,以便 Sphinx 能够找到 unilabos 包
sys.path.insert(0, os.path.abspath(".."))
project = "Uni-Lab"
copyright = "2025, Uni-Lab Community, DP Technology & Peking University"
author = "Uni-Lab Community, DP Technology & Peking University"
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
extensions = [
"myst_parser",
"sphinx.ext.autodoc",
"sphinx.ext.napoleon", # 如果您使用 Google 或 NumPy 风格的 docstrings
"sphinx_rtd_theme"
]
source_suffix = {
".rst": "restructuredtext",
".txt": "markdown",
".md": "markdown",
}
myst_enable_extensions = [
"colon_fence",
"deflist",
"dollarmath",
"html_image",
"replacements",
"smartquotes",
"substitution",
]
templates_path = ["_templates"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
language = "zh"
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
# 设置 HTML 主题为 sphinx-book-theme
html_theme = "sphinx_rtd_theme"
# sphinx-book-theme 主题选项
html_theme_options = {
"repository_url": "https://github.com/用户名/Uni-Lab",
"use_repository_button": True,
"use_issues_button": True,
"use_edit_page_button": True,
"use_download_button": True,
"path_to_docs": "docs",
"show_navbar_depth": 2,
"show_toc_level": 2,
"home_page_in_toc": True,
"logo_only": False,
}
# 设置 HTML 文档的静态文件路径
html_static_path = ["_static"] # 如果有自定义 CSS可以放在 _static 目录中
section_titles = {
"Simple": "## 简单单变量动作函数",
"Organic": """## 常量有机化学操作
Uni-Lab 常量有机化学指令集多数来自 [XDL](https://croningroup.gitlab.io/chemputer/xdl/standard/full_steps_specification.html#),包含有机合成实验中常见的操作,如加热、搅拌、冷却等。
""",
"Bio": """## 移液工作站及相关生物自动化设备操作
Uni-Lab 生物操作指令集多数来自 [PyLabRobot](https://docs.pylabrobot.org/user_guide/index.html),包含生物实验中常见的操作,如移液、混匀、离心等。
""",
"MobileRobot": "## 多工作站及小车运行、物料转移",
"Robot": """## 机械臂、夹爪等机器人设备
Uni-Lab 机械臂、机器人、夹爪和导航指令集沿用 ROS2 的 `control_msgs` 和 `nav2_msgs`
""",
}
import os
from pathlib import Path
def get_conda_share_dir(package_name=None):
"""获取 Conda 环境的 share 目录路径
:param package_name: 可选参数,指定具体包的 share 子目录
:return: Path 对象或 None
"""
# 获取当前 Conda 环境根目录
conda_prefix = os.getenv("CONDA_PREFIX")
if not conda_prefix:
raise EnvironmentError("未检测到激活的 Conda 环境")
# 构建基础 share 目录路径
share_dir = Path(conda_prefix) / "share"
# 如果指定了包名,追加包子目录
if package_name:
share_dir = share_dir / package_name
# 验证路径是否存在
if not share_dir.exists():
print(f"警告: 路径 {share_dir} 不存在")
return None
return share_dir
def generate_action_includes(app):
src_dir = Path(app.srcdir)
print(f"Generating action includes for {src_dir}")
action_dir = src_dir.parent / "unilabos_msgs" / "action" # 修改为你的实际路径
output_file = src_dir / "developer_guide" / "action_includes.md"
# 确保输出目录存在
output_file.parent.mkdir(exist_ok=True)
# 初始化各部分内容
sections = {}
# 仅处理本地消息文件
if action_dir.exists():
for action_file in sorted(action_dir.glob("*.action")):
# 获取相对路径
rel_path = f"../../unilabos_msgs/action/{action_file.name}"
# 读取首行注释
try:
with open(action_file, "r", encoding="utf-8") as af:
first_line = af.readline().strip()
# 提取注释内容(去除#和空格)
section = first_line.lstrip("#").strip()
text = f"""
### `{action_file.stem}`
```{{literalinclude}} {rel_path}
:language: yaml
```
----
"""
if sections.get(section) is None:
sections[section] = text
else:
sections[section] += text
except Exception as e:
print(f"处理文件 {action_file} 时出错: {e}")
else:
print(f"警告: 动作消息目录 {action_dir} 不存在")
ros_action_dirs = []
control_msgs_dir = get_conda_share_dir("control_msgs")
nav2_msgs_dir = get_conda_share_dir("nav2_msgs")
if control_msgs_dir is not None:
ros_action_dirs.append(control_msgs_dir / "action")
if nav2_msgs_dir is not None:
ros_action_dirs.append(nav2_msgs_dir / "action")
for action_dir in ros_action_dirs:
for action_file in sorted(action_dir.glob("*.action")):
# 获取相对路径
rel_path = f"{action_file.absolute()}"
# 读取首行注释
with open(action_file, "r", encoding="utf-8") as af:
# 提取注释内容(去除#和空格)
section = "Robot"
text = f"""### `{action_file.stem}`
```yaml
{open(rel_path, 'r').read()}
```
----
"""
if sections.get(section) is None:
sections[section] = text
else:
sections[section] += text
# 写入内容到输出文件
with open(output_file, "w", encoding="utf-8") as f:
# 按 Section 生成总文档
for section, title in section_titles.items():
content = sections.get(section, "")
if content: # 只有有内容时才写入标题和内容
f.write(f"{title}\n\n")
f.write(content)
def setup(app):
app.connect("builder-inited", generate_action_includes)