Files
worldmodel/plans/hotel_scene_implementation_plan.md
T

19 KiB
Raw Blame History

酒店场景室内建模与物理验证项目详细实施计划

项目概述

本项目旨在构建一套完整的酒店场景数字孪生系统,涵盖公共区域、客房和卫生间三大核心场景,实现从几何重建到物理交互验证的全流程闭环。项目将结合最新的3D重建技术(3DGS、NeRF)、SLAM建图、语义理解和物理世界模型(M-JEPA),为具身智能在真实复杂环境中的落地提供技术验证平台。

核心目标

  1. 几何精度:实现毫米级的三维重建精度
  2. 语义丰富:构建包含物体属性、空间关系的结构化场景图
  3. 物理准确:支持真实物理交互的数字孪生环境
  4. 实时性能:达到实时渲染与在线建图能力
  5. 泛化能力:验证技术方案在不同酒店场景的适用性

一、项目整体架构设计与技术选型

1.1 系统架构总览

graph TB
    A[数据采集层] --> B[感知与建图层]
    B --> C[语义理解层]
    C --> D[物理交互层]
    D --> E[应用验证层]
    
    A1[LiDAR扫描] --> A
    A2[RGB-D相机] --> A
    A3[偏振相机] --> A
    A4[IMU惯性] --> A
    
    B1[SLAM定位] --> B
    B2[3DGS重建] --> B
    B3[点云融合] --> B
    
    C1[YOLO检测] --> C
    C2[SAM分割] --> C
    C3[CLIP特征] --> C
    C4[场景图构建] --> C
    
    D1[M-JEPA模型] --> D
    D2[物理仿真] --> D
    D3[铰接感知] --> D
    
    E1[机器人导航] --> E
    E2[物体操作] --> E
    E3[任务规划] --> E

1.2 分场景技术路线

场景类型 核心挑战 主要技术栈 预期输出
公共区域
大堂、走廊
大尺度、弱纹理
动态干扰多
FAST-LIO2 / R3LIVE
YOLO动态滤除
Hierarchical 3DGS
大规模点云地图
实时渲染模型
客房内部 空间紧凑、遮挡多
家具密集
Gaussian-SLAM / Co-SLAM
SAM + CLIP语义
SceneCAD布局
高精度Mesh
3D场景图
CAD替身
卫生间 高反光、无纹理
镜面/玻璃多
Ref-NeRF / Specular 3DGS
偏振相机
抗反射ToF
抗反光重建
镜面几何分离

1.3 核心技术选型矩阵

SLAM与定位技术

技术方案 适用场景 优势 劣势 选用决策
FAST-LIO2 公共区域 实时性强、抗退化 需LiDAR硬件 主选
R3LIVE 公共区域 视觉-LiDAR紧耦合 计算量大 备选
ORB-SLAM3 客房 纯视觉、成熟 弱纹理易失败 ⚠️ 辅助
Gaussian-SLAM 客房 建图+渲染一体 内存占用高 主选
MonoGS 客房 单目实时 尺度漂移 备选

三维重建技术

技术方案 渲染速度 几何精度 内存占用 可编辑性 选用决策
3D Gaussian Splatting 主选
Instant-NGP ⚠️ 辅助
Mip-NeRF 360 ⚠️ 高质量场景
NeuS / SuGaR Mesh提取

语义理解技术

技术方案 检测速度 分割质量 开放词表 3D投影 选用决策
YOLOv9 实时检测
YOLO-World 开放词表
SAM 精细分割
CLIP N/A 特征提取
Mask3D 3D分割

1.4 软件栈与依赖

核心框架:
  - PyTorch: 2.1+
  - CUDA: 12.1+
  - ROS2: Humble
  
SLAM与重建:
  - FAST-LIO2: C++实现
  - Gaussian-Splatting: 官方实现 + 自定义扩展
  - COLMAP: 位姿初始化
  - Open3D: 点云处理
  
语义理解:
  - Ultralytics: YOLOv9/YOLO-World
  - Segment-Anything: SAM
  - OpenCLIP: 特征提取
  - Detectron2: Mask R-CNN备选
  
物理仿真:
  - Isaac Sim: 主仿真器
  - MuJoCo: 轻量级验证
  - Genesis: 柔体/流体
  
数据管理:
  - HDF5: 大规模数据存储
  - MinIO: 对象存储
  - PostgreSQL + PostGIS: 空间数据库

二、硬件设备与传感器配置方案

2.1 移动采集平台配置

方案A:高精度科研平台(推荐)

平台类型: 定制移动小车 / 手持稳定器

核心传感器:
  LiDAR:
    型号: Livox Mid-360 / Ouster OS1-64
    扫描频率: 10Hz
    测距范围: 0.05-70m
    精度: ±2cm
    
  RGB-D相机:
    型号: Azure Kinect DK / RealSense L515
    分辨率: 1920x1080 @ 30fps (RGB)
    深度范围: 0.25-5.46m
    深度精度: <1% @ 1m
    
  高分辨率相机:
    型号: Sony α7R IV / Canon EOS R5
    分辨率: 61MP / 45MP
    用途: 高质量纹理采集
    
  偏振相机(卫生间专用):
    型号: Lucid Phoenix 5.0 MP
    偏振角度: 0°/45°/90°/135°
    用途: 消除镜面反射
    
  IMU:
    型号: Xsens MTi-630
    频率: 400Hz
    精度: 0.2° (roll/pitch), 1° (yaw)

计算单元:
  主机: NVIDIA Jetson AGX Orin 64GB
  备用: Intel NUC 13 Pro (i7-1360P)
  
存储:
  SSD: 2TB NVMe (现场缓存)
  移动硬盘: 8TB (数据备份)
  
电源:
  电池: 24V 20Ah 锂电池
  续航: 4-6小时连续采集
  
预算: ¥15-20万

方案B:轻量级快速部署(备选)

平台类型: iPhone 15 Pro Max + LiDAR配件

核心传感器:
  内置LiDAR: Apple LiDAR Scanner
  主摄: 48MP (f/1.78)
  超广角: 12MP (f/2.2)
  长焦: 12MP (f/2.8, 5x)
  
配件:
  - Structure Sensor Pro (外接高精度深度)
  - DJI OM 6 稳定器
  
优势:
  - 部署快速,成本低(¥2-3万)
  - 便携性强
  - 软件生态成熟(Polycam, 3D Scanner App
  
劣势:
  - 精度略低于专业设备
  - 大场景扫描效率低
  
适用场景: 快速原型验证、小规模客房扫描

2.2 固定站点补充采集

三脚架全景扫描:
  设备: Matterport Pro3 / Leica BLK360
  用途: 客房全景高精度补充
  分辨率: 134MP 全景照片
  扫描时间: 20秒/站点
  
无人机(公共区域高空视角):
  型号: DJI Mavic 3 Enterprise
  相机: 4/3 CMOS 20MP
  用途: 大堂天花板、中庭俯视

2.3 传感器标定方案

外参标定:
  工具: Kalibr / CamOdoCal
  标定板: AprilTag 6x6 阵列
  流程:
    1. LiDAR-Camera外参标定
    2. 多相机时间同步校准
    3. IMU-Camera外参标定
  精度要求: 平移误差 < 5mm, 旋转误差 < 0.5°

内参标定:
  相机: OpenCV棋盘格标定
  LiDAR: 平面拟合验证
  深度相机: 深度-RGB对齐验证

三、公共区域大规模SLAM建图模块

3.1 技术实现路线

阶段1:多传感器融合SLAM

# 伪代码框架
class PublicAreaSLAM:
    def __init__(self):
        self.lidar_odometry = FAST_LIO2()  # 激光里程计
        self.visual_frontend = ORB_SLAM3()  # 视觉前端
        self.imu_preintegration = IMUPreintegrator()
        self.dynamic_filter = YOLODynamicFilter()  # 动态物体滤除
        
    def process_frame(self, lidar_scan, rgb_image, imu_data):
        # 1. 动态物体检测与掩码
        dynamic_mask = self.dynamic_filter.detect(rgb_image)
        
        # 2. 滤除动态点云
        static_lidar = self.filter_dynamic_points(
            lidar_scan, dynamic_mask
        )
        
        # 3. LiDAR里程计估计
        lidar_pose = self.lidar_odometry.track(static_lidar)
        
        # 4. 视觉特征提取(静态区域)
        visual_features = self.visual_frontend.extract_features(
            rgb_image, mask=~dynamic_mask
        )
        
        # 5. 紧耦合优化
        fused_pose = self.tightly_coupled_optimization(
            lidar_pose, visual_features, imu_data
        )
        
        return fused_pose, static_lidar

关键技术点

  1. 动态滤除策略

    • 使用YOLO-World实时检测行人、行李车等动态物体
    • 将2D检测框投影到3D点云,生成动态点掩码
    • 采用时序一致性检查(连续3帧检测)避免误删
  2. 长走廊退化处理

    • 引入IMU约束防止Z轴漂移
    • 使用曼哈顿世界假设(Manhattan World)约束墙面平行
    • 回环检测:基于Scan Context的LiDAR回环 + DBoW3视觉回环
  3. 大规模地图管理

    • 采用分块(Submapping)策略,每20m×20m一个子图
    • 子图间通过ICP + 特征匹配进行配准
    • 全局位姿图优化(Pose Graph Optimization

阶段2:点云后处理与优化

点云清洗:
  - 统计滤波去除离群点(Statistical Outlier Removal
  - 体素下采样(Voxel Grid, 2cm分辨率)
  - 地面分割与移除(RANSAC平面拟合)
  
点云配准:
  - 粗配准: Fast Global Registration (FGR)
  - 精配准: Colored ICP(结合RGB信息)
  - 多视角融合: Poisson Surface Reconstruction
  
语义标注:
  - 墙面/地面/天花板自动分割
  - 柱子、门、窗户等结构元素提取
  - 与CAD图纸对齐(如有)

阶段3Hierarchical 3DGS训练

# 大规模3DGS训练流程
class HierarchicalGaussianSplatting:
    def __init__(self, point_cloud, camera_poses):
        self.build_hierarchy(point_cloud)
        
    def build_hierarchy(self, pc):
        # 1. 空间八叉树分割
        self.octree = self.build_octree(pc, max_depth=5)
        
        # 2. 每个节点独立训练3DGS
        for node in self.octree.leaf_nodes:
            node.gaussians = self.train_local_3dgs(
                node.points, 
                node.cameras,
                iterations=7000
            )
        
        # 3. 层级LOD构建
        self.build_lod_pyramid()
        
    def render(self, camera, target_fps=30):
        # 根据相机距离动态选择LOD层级
        visible_nodes = self.frustum_culling(camera)
        lod_level = self.select_lod(camera.distance)
        
        return self.hierarchical_render(
            visible_nodes, lod_level
        )

训练参数

  • 初始高斯数量:点云数量 × 1.5
  • 迭代次数:30,000(全局) + 7,000(局部)
  • 学习率:位置 0.00016,旋转 0.001,缩放 0.005
  • 密度控制:每100次迭代进行高斯分裂/剪枝

3.2 实施步骤与时间规划

步骤 任务内容 关键交付物 依赖
3.1 环境勘察与路线规划 采集路线图、站点标记 硬件到位
3.2 传感器标定与测试 标定参数文件 硬件到位
3.3 数据采集(大堂) 原始传感器数据包 3.1, 3.2
3.4 数据采集(走廊) 原始传感器数据包 3.1, 3.2
3.5 SLAM建图与位姿估计 轨迹文件、稀疏点云 3.3, 3.4
3.6 动态滤除与点云融合 静态点云地图 3.5
3.7 Hierarchical 3DGS训练 实时渲染模型 3.6
3.8 质量评估与优化 评测报告、优化模型 3.7

预计工期3-4周

3.3 质量评估指标

几何精度:
  - 点云配准误差: < 3cm (RMSE)
  - 轨迹闭环误差: < 0.5% 总路径长度
  - 墙面平整度: < 2cm 标准差
  
渲染质量:
  - PSNR: > 28 dB
  - SSIM: > 0.85
  - LPIPS: < 0.15
  
性能指标:
  - 渲染帧率: > 30 FPS @ 1080p (RTX 4090)
  - 内存占用: < 16GB
  - 加载时间: < 10秒

四、客房高保真稠密重建模块

4.1 数据采集策略

4.1.1 多模态采集方案

采集模式: 手持RGB-D + 固定站点全景

手持扫描路线:
  1. 入口 → 环绕床铺 → 书桌区域
  2. 衣柜内部(开门扫描)
  3. 窗帘后方、床底等死角
  4. 卫生间门口(不进入,单独处理)
  
固定站点(Matterport:
  - 房间中心点 × 1
  - 床头两侧 × 2
  - 书桌前方 × 1
  - 总计4-5个站点
  
采集密度:
  - 手持扫描: 30cm间隔关键帧
  - 总帧数: 300-500帧/房间
  - 扫描时长: 15-20分钟/房间

4.1.2 弱纹理区域增强

class WeakTextureHandler:
    def __init__(self):
        self.depth_prior = DepthAnything()  # 单目深度估计
        self.lidar_depth = None  # 物理深度真值
        
    def enhance_pose_estimation(self, rgb_frames):
        # 1. 提取稀疏特征点(ORB/SIFT
        sparse_features = self.extract_features(rgb_frames)
        
        # 2. 对于特征稀疏区域,引入深度先验
        for frame in rgb_frames:
            if frame.feature_count < THRESHOLD:
                # 使用深度大模型预测
                depth_prior = self.depth_prior.predict(frame.rgb)
                
                # 与LiDAR深度融合
                if self.lidar_depth is not None:
                    depth_fused = self.fuse_depth(
                        depth_prior, 
                        self.lidar_depth,
                        confidence_weight=0.7  # LiDAR权重更高
                    )
                else:
                    depth_fused = depth_prior
                
                # 生成虚拟特征点
                frame.add_depth_constraints(depth_fused)
        
        # 3. 联合优化相机位姿
        optimized_poses = self.bundle_adjustment(
            sparse_features, depth_constraints
        )
        
        return optimized_poses

4.2 高保真重建流程

4.2.1 位姿估计与初始化

# COLMAP稀疏重建
colmap feature_extractor \
  --database_path database.db \
  --image_path images/ \
  --ImageReader.camera_model PINHOLE \
  --SiftExtraction.use_gpu 1

colmap exhaustive_matcher \
  --database_path database.db \
  --SiftMatching.use_gpu 1

colmap mapper \
  --database_path database.db \
  --image_path images/ \
  --output_path sparse/

4.2.2 3DGS训练与材质解耦

class SpecularGaussianSplatting:
    """处理客房高反光材质的3DGS扩展"""
    
    def __init__(self, config):
        self.gaussians = GaussianModel(config)
        self.enable_pbr = True  # 启用物理渲染
        
    def forward(self, viewpoint_camera):
        # 标准3DGS渲染
        color, depth, alpha = self.gaussians.render(viewpoint_camera)
        
        if self.enable_pbr:
            # 材质解耦:漫反射 + 镜面反射
            diffuse, specular, roughness, metallic = \
                self.decompose_material(color, viewpoint_camera)
            
            # 环境光照贴图
            env_map = self.estimate_environment_map()
            
            # PBR着色
            color_pbr = self.pbr_shading(
                diffuse, specular, roughness, metallic,
                env_map, viewpoint_camera
            )
            
            return color_pbr, depth, alpha
        
        return color, depth, alpha
    
    def decompose_material(self, color, camera):
        """分离漫反射与镜面反射"""
        # 使用多视角一致性约束
        # 漫反射:视角无关
        # 镜面反射:视角相关(遵循反射定律)
        
        # 简化实现:基于法线与视角夹角
        normals = self.estimate_normals()
        view_dir = camera.get_view_direction()
        
        # Fresnel项估计镜面强度
        fresnel = self.schlick_fresnel(normals, view_dir)
        
        diffuse = color * (1 - fresnel)
        specular = color * fresnel
        
        # 粗糙度与金属度估计(可学习参数)
        roughness = self.roughness_map
        metallic = self.metallic_map
        
        return diffuse, specular, roughness, metallic

训练策略

  • 第一阶段(0-7k iter):标准3DGS,学习基础几何
  • 第二阶段(7k-15k iter):启用PBR,解耦材质
  • 第三阶段(15k-30k iter):精细化,优化镜面反射

4.2.3 Mesh提取与拓扑优化

# 使用SuGaR提取高质量Mesh
from sugar import SuGaR

# 1. 从3DGS提取SDF
sdf_extractor = SuGaR(gaussians)
sdf_grid = sdf_extractor.extract_sdf(resolution=512)

# 2. Marching Cubes生成Mesh
from skimage.measure import marching_cubes
vertices, faces, normals, _ = marching_cubes(
    sdf_grid, level=0.0, spacing=(0.01, 0.01, 0.01)
)

# 3. Mesh后处理
import trimesh
mesh = trimesh.Trimesh(vertices, faces, vertex_normals=normals)

# 移除小连通分量
mesh = mesh.split(only_watertight=False)[0]

# 平滑(保持边缘)
mesh = trimesh.smoothing.filter_laplacian(mesh, iterations=3)

# 简化(可选,用于实时仿真)
mesh = mesh.simplify_quadric_decimation(face_count=50000)

# 导出
mesh.export('room_mesh.obj')

4.3 语义理解与场景图构建

4.3.1 2D语义提取

class SemanticExtractor:
    def __init__(self):
        self.sam = SAM()  # Segment Anything
        self.clip = OpenCLIP()  # 特征提取
        self.yolo = YOLOWorld()  # 开放词表检测
        
    def extract_2d_semantics(self, rgb_image):
        # 1. YOLO快速定位已知物体
        detections = self.yolo.detect(
            rgb_image,
            text_prompts=[
                "bed", "desk", "chair", "TV", "lamp",
                "curtain", "wardrobe", "nightstand"
            ]
        )
        
        # 2. SAM精细分割
        masks = []
        for det in detections:
            mask = self.sam.segment(
                rgb_image,
                box_prompt=det.bbox
            )
            masks.append(mask)
        
        # 3. 提取CLIP特征
        features = []
        for mask in masks:
            masked_region = rgb_image * mask
            clip_feat = self.clip.encode_image(masked_region)
            features.append(clip_feat)
        
        return {
            'masks': masks,
            'features': features,
            'labels': [det.label for det in detections],
            'boxes': [det.bbox for det in detections]
        }

4.3.2 3D特征场融合

class SemanticFeatureField:
    """将2D语义特征提升到3D空间"""
    
    def __init__(self, gaussians, camera_poses):
        self.gaussians = gaussians
        self.cameras = camera_poses
        self.feature_dim = 512  # CLIP特征维度
        
        # 为每个高斯球添加语义特征
        self.semantic_features = nn.Parameter(
            torch.zeros(len(gaussians), self.feature_dim)
        )
        
    def project_2d_to_3d(self, semantic_2d_list):
        """多视角2D特征投影到3D高斯球"""
        
        for view_idx, sem_2d in enumerate(semantic_2d_list):
            camera = self.cameras[view_idx]
            
            # 渲染深度图,获取每个像素对应的高斯球ID
            gaussian_ids = self.render_gaussian_id_map(camera)
            
            # 将2D特征分配给对应的3D高斯球
            for mask, feature in zip(sem_2d['masks'], sem_2d['features']):
                # 获取mask覆盖的高斯球
                affected_gaussians = gaussian_ids[mask > 0.5]
                
                # 累积特征(后续取平均)
                for gid in affected_gaussians.unique():
                    self.semantic_features[gid] += feature
                    self.feature_count[gid] += 1
        
        # 归一化(多视角平均)