[{"content":"实验部分 周三晚上和老师讨论的思路是让我找师兄讨论下手物分离，然后先从简单的平面仿真做起；\n我回去想了想，换了个想法，因为既然最后物体的SDF场是由NeuralFeels给出的，那么我其实只需要验证下对软体物体仿真的部分就可以了，对3D表示的精确度没有要求。\n那么现在的问题是从我拍的照片中恢复出物体的3d表示，所以我的想法是就用dino+sam+zeros123+InstantMesh恢复出一个3D物体的mesh表示，然后再做仿真就好了。\n输入的原始图片如下：\n然后使用dino，这个模型能够根据文字提示把图片中的内容圈出来\n输入提示词 \u0026ldquo;a star\u0026rdquo; 过dino得到下面这个结果\n这个模型会输出一个检测框（列表，每个元素是一个四维张量，分别是检测框的长宽和xy位置）以及文字+得分(如：a star (0.39))\n可以看得出来这个dino模型可能会出现误判，反正我先不管了，就用得分高的那个检测目标和方框，经过SAM分割，输出结果如下：\n然后用zeros123生成多视角的图片，输入是上面那个用SAM分割好的图片，输出结果如下：\n这之后我用InstantMesh重建了物体的mesh，结果如下\n至此已经得到了物体的mesh了(虽然不太准)\n然后我准备先整理下代码，继续在此基础上做我的仿真实验。\n组合生成的调研 还有之前老师让我去调研的几个组合生成相关的工作，这几次组会都没来得及讲，所以我就简单介绍下\nTwo by Two 题目 ：Two by Two : Learning Multi-Task Pairwise Objects Assembly for Generalizable Robot Manipulation\nCVPR2025 04.06 网页\n总结： 输入两个需要装配的物体，比如插座和插头，这个工作是一个数据集，然后训练了一个网络，能够把两个物体的点云对齐，比如把插头和插座对准。\n以下是细节：\n让机器人成功完成装配之类的任务需要对对象对之间的空间关系进行精确推理。机器人需要准确估计每个物体的 6D 姿态，包括它们在空间中的方向和位置。 所以这篇论文的主要创新之处就在于考虑了物体之间的空间关系吧。\n2BY2数据集​​： ​​规模与多样性​​：第一个大型组装数据集，包含517对物体、1034个实例，覆盖18个细粒度任务（如插头插入、鲜花插瓶、面包放入烤面包机等）。\n​​标注信息​​：提供6D姿态（平移+旋转）和对称性标注，模拟真实场景中的物理约束。\n​​任务分类​​：分为三大类（Lid Covering, Inserting and High Precision Placing），每类进一步细分为具体任务（如钥匙开锁、硬币存钱罐）。\n工作流 具体实现方法 解决的问题是日常成对物体组装任务中的6D姿态估计问题​​，即在三维空间中对两个物体进行精确的相对位姿（位置+旋转）预测，使其能够完成功能性组装（如插头插入插座、盖子盖在瓶子上等）。\n先对之前的数据集作了一个处理，分成两部分，物体 B 是底座或接收组件，例如螺母、花瓶、邮筒。物体 A 是配件组件，例如螺栓、花朵、邮件。\n输入​​：\n两个物体的点云 $P_{A}$ 插入物体，如插头）和$P_{A}$（基础物体，如插座），每个点云为1024个点的坐标集合。\n​​输出​​：\n两个SE(3)变换矩阵 ($T_{B}, R_{B}$) 和 ($T_{A}, R_{A}$)，然后分别将$P_{A}$和$P_{B}$变换到预定义的Canonical Space，使其在规范空间内完成正确组装。\n​​规范空间​​：根据任务类型定义的基础坐标系。例如： ​​放置类任务​​（如花瓶）：物体稳定放置在XY平面，Z轴垂直向上。 ​​插入类任务​​（如插座）：基础物体固定在XZ平面（模拟墙面），插入方向沿Y轴\n方法：\n网络分为两个分支，​​模仿人类分步组装逻辑​​（如先固定插座，再插入插头）\nBranch B（基础物体预测）\n两尺度Vector Neuron DGCNN​​：提取$SE(3)$等变特征（旋转/平移时特征同步变换）。\n​​MLP预测头​​：从特征中直接预测旋转矩阵$R_B$和平移向量$T_B​$\nBranch A\n基于Object B的预测位姿，预测Object A（如插头）的位姿\n将Object B的SO(3)不变特征（与旋转无关）与Object A的SE(3)等变特征​​点乘融合​​，保留几何对齐信息。\n​​MLP预测头​​：输出$R_A$和$T_A$\n训练策略 分步独立训练​​\n​​Branch B训练​​：使用Object B的规范位姿真值（无需考虑Object A）。\n​​Branch A训练​​：固定Branch B，使用Object B的​​真值位姿​​（避免预测误差传递）。\n​​推理阶段​​：先预测Object B位姿，再基于此预测Object A位姿。\nloss 分两个，一个是平移loss，$\\mathcal{L}_{\\mathrm{trans}}=\\|T_{\\mathrm{pred}}-T_{\\mathrm{gt}}\\|_1$，另一个是旋转loss，$\\mathcal{L}_{\\mathrm{rot}}=\\arccos\\left(\\frac{\\mathrm{tr}(R_{\\mathrm{gt}}R_{\\mathrm{pred}}^T)-1}{2}\\right)$\n​​跨物体特征融合​​：通过点乘显式建模功能关系（如孔-轴匹配）\nInfinite Mobility 网页\n总结： 定死URDF的文件框架，在此基础上生成各种各样零件的排列方式，从而得到铰接的物体。\n以下是细节部分：\n这篇文章要解决的问题是如何高效地生成大规模高质量的关节物体，以满足具身AI相关任务的需求。现有的方法要么是基于数据驱动的，要么是基于模拟的，这两种方法都受到训练数据规模和质量或模拟的真实性和劳动强度的限制。\n核心原理 我觉得这篇文章的一个比较好的思路是： 每个刚体都描述为一个链接，每个关节是两个链接之间的连接。通过这种结构，铰接对象可以描述为树状结构，其中每个节点代表一个链接，每条边代表一个关节。 从根节点开始，通过语义规则递归添加子节点，生成必要部件（比如椅子的轮子等），同时允许多样化扩展。\n部分URDF截图：\n定义物体： 生成物体之间的连接： 部分物理属性（如摩擦、阻尼）尚未自动化生成，而且底层的组件部分还是有限的(blender api + 本地库)，并非生成得到，但是这个用trellis3D之类的会非常好生成，因为只需要mesh和mtl了\n结果 不过对于lay out布局来说，目前还是手动指定的，比如下图就是作者在论文中给出的 但是据作者所说，他们应该准备做生成物体布局的工作了，估计今年下半年能够做出来\n还有一个缺点是这篇论文生成的物体可能不能拆卸或组装\nPartRM PartRM: Modeling Part-Level Dynamics with Large Cross-State Reconstruction Model\nCVPR2025 03.19 网页\n总结： 也是3D铰接物体的生成，区别是之前的工作更加侧重于生成 大量的铰接物体以供训练，这个工作侧重于从一张图片中推理出铰接物体的未来运动（比如给一个关闭的门，能预测出门打开的样子），代码我还没来得及看\n以下是具体细节：\n问题 这篇论文主要的工作集中于部件级动态建模方面\n1 提高了动态建模的精度和一致性：现有方法如Puppet-Master和DragAPart通常只能处理单视图图像或视频。而PartRM能够生成3D-aware的部件级运动，并且在多视角下保持一致性 ；也就是说之前的工作都是在平面上的抽屉开合，这个工作有物体的三维表示（高斯）\n2 PartRM提出了PartDrag-4D数据集，该数据集提供了20,000多个部件状态的多视角图像，极大地丰富了训练数据。\n3 PartRM采用了两阶段训练策略，分别处理运动学习和外观/几何学习，避免了灾难性遗忘，从而提高了模型的泛化能力。不过我感觉这个两阶段训练处处都有，不能算创新?\n输入\u0026amp;输出 Pipeline\n任务定义如下： 给定单张铰链物体的图像,一张静态的物体图像（例如微波炉的正面图） $o_t$ 和用户指定的拖拽 $a_t$（表示部件的运动方向和幅度，一个视图，像素坐标级别移动）（这个$a_t$表示从门关闭的位置到门打开的位置的运动）\n输出t+N时刻(N任意) PartRM会输出门在整个过程中从关闭到打开的每个时刻的运动信息。例如，它会给出门的具体位置，门的移动幅度，以及在不同时间点的姿态，而且由于是高斯渲染，所以能保证多视角的一致性。\n输入：一张包含物体（如门）的单视图图像，以及门的起始位置和终点位置的拖拽交互信息（这些位置是通过像素坐标指定的）。\n输出：模型生成物体的3D表示，以及在不同时间点和视角下的物体状态和运动轨迹。\n工作流 首先会利用 Zero123++ 生成输入的多视角图像，然后对输入的拖拽在用户希望移动的 Part 上进行传播。\n这个part是利用SAM分割得到的\n这些多视角的图像和传播后的拖拽会输入网络中，这个网络会对输入的拖拽进行多尺度的嵌入，然后将得到的嵌入拼接到重建网络的下采样层中。\n因为网络可能不一定能识别到拖拽的区域。因此对拖拽进行传播到需要被拖拽部分的各个区域，使得后续网络感知到需要被拖拽的区域，为此我们设计了一个拖拽传播策略。如图所示，我们首先拿用户给定的拖拽的起始点输入进 Segment Anything 模型中得到对应的被拖拽区域的掩码，然后在这个掩码区域内采样一些点作为被传播拖拽的起始点，这些被传播的拖拽的强度和用户给定的拖拽的强度一样。\n嵌入的过程如下： 在训练过程中，采用两阶段训练方法，第一阶段学习 Part 的运动，利用高斯库里的 3D 高斯进行监督，第二阶段学习外观，利用数据集里的多视角图像进行监督。\n数据集 文中选取了 8 种铰链物体（其中 7 种用于训练， 1 种用于测试），共 738 个 mesh。对于每个 mesh，如上图所示，文中使其中某个部件在两种极限状态（如完全闭合到完全开启）间运动至 6 个状态，同时将其他部分状态 设置为随机，从而产生共 20548 个状态，其中 20057 个用于训练，491 个用于测试。为渲染多视角图像，我们利用 Blender 为每个 mesh 渲染了 12 个视角的图像。对于两个状态之间拖拽数据的采样，我们在铰链物体运动部件的 Mesh 表面选取采样点，并将两个状态中对应的采样点投影至 2D 图像空间，即可获得对应的拖拽数据。\n泛化到未知的数据 因为只指定了物体运动的启动和终点，所以在比较平滑的运动上能够取得比较好的效果，但是应该也不会太好。\n还有一个比较严重的问题，就是他们训练的时候是给了blender中的模型，比如一个抽屉，那么是可以学习抽屉从关闭到打开的过程的，因为模型见过抽屉里的东西，但是泛化到未知环境的时候，怎么生成那些没见过的视图的细节呢？\n而且文中只提到了一点点应用于操作上的内容，不过我没明白这种生成方式是怎么应用上去的，理论上机器人不可能和高斯交互吧，可能要具体看看代码才知道。\nCAST CAST: Component-Aligned 3D Scene Reconstruction from an RGB Image\n从单张RGB图像重建高质量3D场景，核心是通过分解场景为独立物体生成，并结合根据关系图定义的接触和支撑约束，利用SDF优化物体姿态，消除穿透和漂浮现象，确保场景物理合理性，实现高保真和物理合理的重建\n虽然代码没有开源，但是这个工作是我目前见过的看起来效果最好的场景重建，论文的细节我准备下周花点时间去看看。\n其重建出的3D场景的结果如下：\n","date":"2025-05-08T18:28:50+08:00","image":"https://Peraspera1.github.io/cover.png","permalink":"https://Peraspera1.github.io/p/report0508/","title":"Report0508"},{"content":"由于在低多样性数据上训练的模型存在局限性，灵巧的机械手通常难以在复杂环境中有效地泛化。然而，现实世界本质上呈现了无限的场景范围，因此无法考虑所有可能的变化.\n**​​现有方法的局限​​：**传统灵巧抓取方法（优化型或基于学习的方法）依赖有限多样性的数据集，难以适应真实场景中无限的变化。扩散模型虽能生成多样抓取，但存在采样效率低、物理合理性不足的问题\n一个自然的解决方案是让机器人从复杂环境中的经验中学习，这种方法类似于进化，系统通过持续反馈进行改进，从失败和成功中学习，并迭代以实现最佳性能。 也就是在动态环境中实现抓取策略的持续优化，同时平衡效率与物理可行性。\n问题定义 输入​​：物体点云 $O\\in\\mathbb{R}^{N\\times3}$ ，表示物体的几何形状。\n输出：灵巧手的抓取姿态参数 x\n方法 对于一个物体点云O，模型会通过预测噪声，然后去噪得到多个手部姿态的样本。这个样本里有正样本和负样本（判断正负样本的方式是在仿真加扰动，有一些metrics去判断，也可以由人来选择）。然后根据HPO的损失函数来调整模型参数（如LoRA微调），使未来生成的姿态更偏向成功分布，而非直接修改去噪步骤的参数。\nHPO ​Handpose-wise Preference Optimization (HPO) 基于偏好对齐的进化式抓取生成\n​​目标​​：通过对比正样本（成功抓取）和负样本（失败抓取）的差异，优化模型生成抓取姿态的后验概率分布。\n使用Bradley-Terry模型定义偏好概率： $p_\\mathrm{BT}(x_0^w\\succ x_0^l)=\\sigma(r(x_0^w)-r(x_0^l))$\nHPO损失函数:\n$\\mathcal{L}_{\\mathrm{HPO}}=\\mathbb{E}\\log\\sigma\\left(\\sum_{i=1}^{N_{\\mathrm{suc}}}\\log\\frac{\\pi_\\theta(x_{n-1}^i|x_n^i)}{\\pi_{\\mathrm{ref}}(x_{n-1}^i|x_n^i)}-\\sum_{j=1}^{N_{\\mathrm{fail}}}\\log\\frac{\\pi_\\theta(x_{n-1}^j|x_n^j)}{\\pi_{\\mathrm{ref}}(x_{n-1}^j|x_n^j)}\\right)$\n通过正样本（成功抓取）和负样本（失败抓取）的对数概率比优化策略，使模型偏好高质量抓取。\n​​Bradley-Terry模型 Bradley-Terry模型是一种用于​​配对比较（Pairwise Comparison）​​的概率模型，最初用于预测竞技比赛中选手的胜负概率。\n每个选项（如选手或抓取姿态）有一个隐式“强度值”​​（即奖励函数值 r(x)）。\nExample: 选手A的强度值 r(A)=2，选手B的强度值 r(B)=1 根据Bradley-Terry模型，A战胜B的概率为 $\\frac{e^2}{e^2+e^1}\\approx73\\%$\n在论文中，抓取姿态的“强度值”由隐式奖励函数 r(x) 表示（显式的奖励函数，如“接触点数越多越好”），代表抓取姿态的质量（如稳定性、防穿透性），那么偏好概率公式由以下方程表示：\n$p_{\\mathrm{BT}}(x^w\\succ x^l)=\\sigma(r(x^w)-r(x^l))=\\frac{1}{1+e^{-(r(x^w)-r(x^l))}}$\n$x^w$是成功样本，$x^l$是失败样本，如果 $x^w$ 比 $x^l$更优,则 $r(x^w)\u003er(x^l)$ ,概率趋近于1;反之趋近于0。\nPCM PCM的核心，一是通过一致性模型框架压缩推理步骤，而是引入物理约束。\n一致性模型 从预训练的扩散模型（教师模型）中蒸馏出一个轻量级的一致性模型（学生模型），从而将扩散模型的去噪过程（数百步）压缩为​​极少数步骤​​（2-8步），直接学习从噪声到干净数据的映射\n自洽性 模型在不同时间步（timestep）对同一噪声输入的预测结果指向同一数据点​​（即去噪后的干净数据）。例如，输入一个噪声样本$x_t$, (对应时间步 t)，模型应直接预测出最终去噪结果$x_0$。输入另一个噪声样本$x_{t'}$，对应时间步$t'$，模型预测的$x_0$应与前者的结果一致。\n那么自洽性损失的定义如下：\n$\\mathcal{L}_{\\text{consistency}}=\\mathbb{E}_{t,t^{\\prime}}\\left[\\|f_\\theta(x_t,t)-f_\\theta(x_{t^{\\prime}},t^{\\prime})\\|^2\\right]$\n在训练时，随机采样两个时间步 t 和 t\u0026rsquo;，并通过数值 ODE 求解器（如 DDIM）生成相邻时间步的噪声样本$x_t$和$x_{t'}$。 模型需预测两者的去噪结果$x_0$，并通过损失函数强制它们的预测一致。\n模型蒸馏 教师模型​​：传统扩散模型需要 100+ 步去噪（如 DDPM），每一步迭代修正噪声。\n​​学生模型（PCM）​​：通过​​蒸馏（Distillation）​​将教师模型的多步去噪过程压缩为​​单步映射​​（从任意噪声$x_t$直接预测$x_0$）。\n教师模型使用大规模抓取数据集（如 DexGraspNet、MultiDex）训练传统的扩散模型。\n学生模型在推理时需满足物理可行性（如避免穿透、保持接触稳定性）。为此，在采样过程中引入​​梯度引导​​：\n$\\hat{\\mu}_\\theta(x_t,t)=\\mu_\\theta(x_t,t)+\\sum_{i=1}^m\\gamma_i\\nabla_{x_t}\\mathcal{L}_{\\mathrm{PA}_i}(F_\\theta(x_t,t),\\epsilon_\\theta)$\n学生模型本身是单步映射，但实际应用中通过 2-8 步迭代逐步修正噪声，以提升稳定性。\n评估指标 Suc.6 Success rate Suc.6 measures the proportion of grasping poses where the object’s displacement does not exceed 2 cm in all six axial directions (±X, ±Y , ±Z), evaluating multi-directional stability.\n在仿真器中给物体一个扰动，看物体在六个方向上的移动会不会超过2cm。需要六个方向都小于2cm才算成功。\nSuc.1 Suc.1 measures the proportion where displacement does not exceed 2cm in at least one direction, assessing single-direction stability.\n在仿真器中给物体一个扰动，看物体在单个方向上的移动会不会超过2cm。\nPen. Pen. indicates the maximum penetration depth (mm) between the hand and the object, with lower values suggesting more physically plausible grasps.\n手与物体之间的最大穿透深度 （mm），值越低表示物理上越合理。\n结果如下（论文中的metrics似乎单位错了？）：\n手部姿态参数表示​ 抓取姿态 x 由三部分组成： $x=\\left\\{\\theta_h\\in\\mathbb{R}^{24},T_{\\mathrm{global}}\\in\\mathbb{R}^3,R_{\\mathrm{global}}\\in SO(3)\\right\\}$\n​关节角度\n​​参数​​： $x= \\theta_h\\in \\mathbb{R}^{24}$\n​​含义​​：控制手部24个关节的弯曲角度（如手指的屈伸、侧展）。\n​​作用​​：决定手指的局部形状，例如手指如何包裹物体。\n​​全局平移\n​​参数​​： $T_{\\mathrm{global}}\\in\\mathbb{R}^3$\n​​含义​​：手部基坐标系（如掌心）在三维空间中的平移坐标 (x,y,z)。\n​​作用​​：确定手部相对于目标物体的位置（如手距离物体的远近）。\n​​全局旋转\n​​参数​​：$ R_{\\mathrm{global}}\\in SO(3)$\n​​含义​​：手部基坐标系的三维旋转矩阵（属于特殊正交群 SO(3)），表示手部的朝向（如掌心朝上/朝下）。\n​​作用​​：决定手部在空间中的摆放方向，影响抓取角度（如正握、侧握）\n","date":"2025-04-25T16:03:07+08:00","image":"https://Peraspera1.github.io/images/EvolvingGrasp/cover.png","permalink":"https://Peraspera1.github.io/p/evolvinggrasp/","title":"EvolvingGrasp"},{"content":"一个对于近期组合生成论文的总结\nPartRM 论文题目：\nPartRM: Modeling Part-Level Dynamics with Large Cross-State Reconstruction Model\nCVPR2025 03.19 网页\n问题 这篇论文主要的工作集中于部件级动态建模方面\n1 提高了动态建模的精度和一致性：现有方法如Puppet-Master和DragAPart通常只能处理单视图图像或视频。而PartRM能够生成3D-aware的部件级运动，并且在多视角下保持一致性 ；也就是说之前的工作都是在平面上的抽屉开合，这个工作有物体的三维表示（高斯）\n2 PartRM提出了PartDrag-4D数据集，该数据集提供了20,000多个部件状态的多视角图像，极大地丰富了训练数据。\n3 PartRM采用了两阶段训练策略，分别处理运动学习和外观/几何学习，避免了灾难性遗忘，从而提高了模型的泛化能力。不过我感觉这个两阶段训练处处都有，不能算创新?\n输入\u0026amp;输出 Pipeline\n任务定义如下： 给定单张铰链物体的图像,一张静态的物体图像（例如微波炉的正面图） $o_t$ 和用户指定的拖拽 $a_t$（表示部件的运动方向和幅度，一个视图，像素坐标级别移动）（这个$a_t$表示从门关闭的位置到门打开的位置的运动）\n输出t+N时刻(N任意) PartRM会输出门在整个过程中从关闭到打开的每个时刻的运动信息。例如，它会给出门的具体位置，门的移动幅度，以及在不同时间点的姿态，而且由于是高斯渲染，所以能保证多视角的一致性。\n输入：一张包含物体（如门）的单视图图像，以及门的起始位置和终点位置的拖拽交互信息（这些位置是通过像素坐标指定的）。\n输出：模型生成物体的3D表示，以及在不同时间点和视角下的物体状态和运动轨迹。\n工作流 首先会利用 Zero123++ 生成输入的多视角图像，然后对输入的拖拽在用户希望移动的 Part 上进行传播。\n这个part是利用SAM分割得到的\n这些多视角的图像和传播后的拖拽会输入网络中，这个网络会对输入的拖拽进行多尺度的嵌入，然后将得到的嵌入拼接到重建网络的下采样层中。\n因为网络可能不一定能识别到拖拽的区域。因此对拖拽进行传播到需要被拖拽部分的各个区域，使得后续网络感知到需要被拖拽的区域，为此我们设计了一个拖拽传播策略。如图所示，我们首先拿用户给定的拖拽的起始点输入进 Segment Anything 模型中得到对应的被拖拽区域的掩码，然后在这个掩码区域内采样一些点作为被传播拖拽的起始点，这些被传播的拖拽的强度和用户给定的拖拽的强度一样。\n嵌入的过程如下： 在训练过程中，我们采用两阶段训练方法，第一阶段学习 Part 的运动，利用高斯库里的 3D 高斯进行 监督，第二阶段学习外观，利用数据集里的多视角图像进行监督。\n数据集 文中选取了 8 种铰链物体（其中 7 种用于训练， 1 种用于测试），共 738 个 mesh。对于每个 mesh，如上图所示，文中使其中某个部件在两种极限状态（如完全闭合到完全开启）间运动至 6 个状态，同时将其他部分状态 设置为随机，从而产生共 20548 个状态，其中 20057 个用于训练，491 个用于测试。为渲染多视角图像，我们利用 Blender 为每个 mesh 渲染了 12 个视角的图像。对于两个状态之间拖拽数据的采样，我们在铰链物体运动部件的 Mesh 表面选取采样点，并将两个状态中对应的采样点投影至 2D 图像空间，即可获得对应的拖拽数据。\n泛化到未知的数据 因为只指定了物体运动的启动和终点，所以在比较平滑的运动上能够取得比较好的效果，但是应该也不会太好。\n还有一个比较严重的问题，就是他们训练的时候是给了blender中的模型，比如一个抽屉，那么是可以学习抽屉从关闭到打开的过程的，因为模型见过抽屉里的东西，但是泛化到未知环境的时候，怎么生成那些没见过的视图的细节呢？\n而且文中只提到了一点点应用于操作上的内容，不过我没明白这种生成方式是怎么应用上去的，理论上机器人不可能和高斯交互吧。总的来说，无论是研究方法还是目标都挺无聊的。\nInfinite Mobility 论文题目：\nInfinite Mobility: Scalable High-Fidelity Synthesis of Articulated Objects via Procedural Generation\n网页\n这篇文章要解决的问题是如何高效地生成大规模高质量的关节物体，以满足具身AI相关任务的需求。现有的方法要么是基于数据驱动的，要么是基于模拟的，这两种方法都受到训练数据规模和质量或模拟的真实性和劳动强度的限制。\n核心原理 我觉得这篇文章的一个比较好的思路是： 每个刚体都描述为一个链接，每个关节是两个链接之间的连接。通过这种结构，铰接对象可以描述为树状结构，其中每个节点代表一个链接，每条边代表一个关节。 从根节点开始，通过语义规则递归添加子节点，确保必要部件生成，同时允许多样化扩展。\n部分URDF截图：\n定义物体： 生成物体之间的连接： 部分物理属性（如摩擦、阻尼）尚未自动化生成，而且底层的部分还是有限的(blender api + 本地库)，并非生成得到，但是这个用trellis3D之类的会非常好生成，因为只需要mesh和mtl了\n结果 不过对于lay out布局来说，目前还是手动指定的，比如下图就是作者在论文中给出的 而且这篇论文生成的物体可能不能拆卸或组装吧？\nTwo by Two 论文题目：\nTwo by Two : Learning Multi-Task Pairwise Objects Assembly for Generalizable Robot Manipulation\nCVPR2025 04.06 网页\n让机器人成功完成装配之类的任务需要对对象对之间的空间关系进行精确推理。机器人需要准确估计每个物体的 6D 姿态，包括它们在空间中的方向和位置。 所以这篇论文的主要创新之处就在于考虑了物体之间的空间关系吧。\n2BY2数据集​​： ​​规模与多样性​​：第一个大型组装数据集，包含517对物体、1034个实例，覆盖18个细粒度任务（如插头插入、鲜花插瓶、面包放入烤面包机等）。\n​​标注信息​​：提供6D姿态（平移+旋转）和对称性标注，模拟真实场景中的物理约束。\n​​任务分类​​：分为三大类（Lid Covering, Inserting and High Precision Placing），每类进一步细分为具体任务（如钥匙开锁、硬币存钱罐）。\n工作流 具体实现方法 解决的问题是日常成对物体组装任务中的6D姿态估计问题​​，即在三维空间中对两个物体进行精确的相对位姿（位置+旋转）预测，使其能够完成功能性组装（如插头插入插座、盖子盖在瓶子上等）。\n先对之前的数据集作了一个处理，分成两部分，物体 B 是底座或接收组件，例如螺母、花瓶、邮筒。物体 A 是配件组件，例如螺栓、花朵、邮件。\n输入​​：\n两个物体的点云 $P_{A}$ 插入物体，如插头）和$P_{A}$（基础物体，如插座），每个点云为1024个点的坐标集合。\n​​输出​​：\n两个SE(3)变换矩阵 ($T_{B}, R_{B}$) 和 ($T_{A}, R_{A}$)，然后分别将$P_{A}$和$P_{B}$变换到预定义的​​规范空间​​（Canonical Space），使其在规范空间内完成正确组装。\n​​规范空间​​：根据任务类型定义的基础坐标系。例如： ​​放置类任务​​（如花瓶）：物体稳定放置在XY平面，Z轴垂直向上。 ​​插入类任务​​（如插座）：基础物体固定在XZ平面（模拟墙面），插入方向沿Y轴\n方法：\n网络分为两个分支，​​模仿人类分步组装逻辑​​（如先固定插座，再插入插头）\nBranch B（基础物体预测）\n两尺度Vector Neuron DGCNN​​：提取$SE(3)$等变特征（旋转/平移时特征同步变换）。\n​​MLP预测头​​：从特征中直接预测旋转矩阵$R_B$和平移向量$T_B​$\nBranch A\n基于Object B的预测位姿，预测Object A（如插头）的位姿\n将Object B的SO(3)不变特征（与旋转无关）与Object A的SE(3)等变特征​​点乘融合​​，保留几何对齐信息。\n​​MLP预测头​​：输出$R_A$和$T_A$\n训练策略 分步独立训练​​\n​​Branch B训练​​：使用Object B的规范位姿真值（无需考虑Object A）。\n​​Branch A训练​​：固定Branch B，使用Object B的​​真值位姿​​（避免预测误差传递）。\n​​推理阶段​​：先预测Object B位姿，再基于此预测Object A位姿。\nloss 分两个，一个是平移loss，$\\mathcal{L}_{\\mathrm{trans}}=\\|T_{\\mathrm{pred}}-T_{\\mathrm{gt}}\\|_1$，另一个是旋转loss，$\\mathcal{L}_{\\mathrm{rot}}=\\arccos\\left(\\frac{\\mathrm{tr}(R_{\\mathrm{gt}}R_{\\mathrm{pred}}^T)-1}{2}\\right)$\n​​跨物体特征融合​​：通过点乘显式建模功能关系（如孔-轴匹配）\n","date":"2025-04-17T21:58:56+08:00","image":"https://Peraspera1.github.io/images/assemblyReport01/cover2.jpg","permalink":"https://Peraspera1.github.io/p/assemblyreport01/","title":"AssemblyReport01"},{"content":"信息概览 Science Robotics\n论文题目： NeuralFeels with neural fields: Visuotactile perception for in-hand manipulation\n论文单位： CMU\n是否开源： 是\n总结： 为了实现类人灵巧操作，机器人必须理解和推理其操作物体的空间关系。特别是在手内操作中，机器人需要估计物体的姿态（位姿）和形状。传统的机器人视觉系统通常面临视觉遮挡的问题，当物体被手或环境遮挡时，视觉数据会变得不完整，从而影响精度。\nNeuralFeels方法使用了视觉（RGB-D摄像头）、**触觉（基于视觉的触觉传感器）和本体感知（机器人关节角度）**数据。这些数据通过在线神经场（Neural Field）模型进行处理，结合了多种感知输入，以获得更精确的物体位姿和形状估计\n作者使用了Signed Distance Field (SDF)，这是一种基于距离的表示方法，可以高效地表示物体的表面。\nNeuralFeels方法的一个关键特性是在线学习。在物体与机器人手进行交互时，系统会实时更新物体的3D表示（SDF）和位姿\n工作流 系统首先通过视觉（RGB-D相机）和触觉（指尖DIGIT传感器）获取数据，利用​​Segment Anything Model（SAM）​​分割物体区域并排除手部遮挡，同时通过预训练的​​触觉变压器​​从触觉图像中提取接触深度；随后，前端处理生成的点云与深度信息输入后端，通过​​神经符号距离场（SDF）​​建模物体几何形状，并构建​​位姿图​​（包含SDF约束、帧间ICP配准和位姿平滑因子），采用交替优化策略——即固定位姿时通过梯度下降更新神经场参数，固定神经场时通过非线性优化（Levenberg-Marquardt算法）求解物体位姿，同时动态管理关键帧以平衡计算效率与全局一致性，最终在在线交互中实现物体形状的渐进式重建与姿态的稳定跟踪，触觉数据在视觉遮挡或噪声场景下显著补全局部几何信息，提升系统鲁棒性。\n度量指标 Pose Metric（位姿度量） 首先是位姿，从估计的网格中下采样一些点，并与离其最近的真实点作差\n传统的成对距离方法需要在估计点和真实点之间建立逐对对应关系，对于每个估计点，都需要找到多个真实点并计算距离，这样会导致计算量迅速增加，尤其是当物体复杂或者有大量点时，计算量会非常庞大。\nADD-S通过只计算每个估计点和最近点的距离，避免了这种逐对匹配，大大减少了计算的复杂度。每个点只需要找到对应的最近点，而不需要考虑所有可能的点对，这样可以大幅加速计算过程。\n？？不过这样难道不会陷入局部最优吗？得去代码里仔细看看\nShape Metric（形状度量） 形状度量用来衡量物体形状的重建精度。为了评估物体的形状重建，作者使用了 F-score，这是一个结合了精度（Precision）和召回率（Recall）的指标，通常用于多视角重建任务。\n精度（Precision） 精度衡量的是重建的表面点与真实表面点之间的匹配质量。具体来说，它计算的是：\n重建的点集中有多少百分比的点，在距离真实表面点 $\\tau$（例如5毫米）以内。\n召回率（Recall） 召回率衡量的是真实物体表面点被重建点覆盖的程度。具体来说，它计算的是：\n真实的物体表面点中有多少百分比的点，可以在重建的点集里找到，并且其距离小于 $\\tau$。\nF-score 是精度和召回率的调和平均值（harmonic mean），这可以综合考量重建的准确度和完整度，得出一个[0,1]的评分。 F-score 的值越接近 1，表示重建的物体表面越精确，重建的点与真实点之间的距离越小，且重建点尽可能多地覆盖了真实表面。\n细节 物体的对齐：为了避免初始化阶段的误差，作者在实验中假设物体的初始位姿是已知的，并且它与真实位姿是对齐的。这意味着，尽管物体的初始位姿是在实验开始时设定的，物体的质心和主轴已经在某种程度上与地面真值对齐.初始化时，物体的坐标系是通过CAD模型的几何质心和主轴方向来设置的，确保物体坐标系与实际操作中的初始姿势匹配。为了保证后续重建的物体位姿不会从中受益，作者在手内物体旋转的5s后才开始做物体位姿和形状的测量，专注与后续的重建和跟踪。\n由于细小误差的积累，且没有回环检测，那么随着时间的累积，物体的pose误差会不断累计，不过作者并没有这方面的改进，只是说明他们大部分的实验的形状估计并没有随着时间的延长而恶化。\n目标 增量式地重建物体，在线地同时优化网络权重-\u0026gt;更新SDF，物体位姿\n有一个灵巧手在拿着物体旋转，这个旋转的策略应该是给定的\n输入RGBD图像，四个手指的触觉传感器，以及机器人自身关节角旋转的参数\nkey insights 神经场（Neural Fields）是一种利用神经网络表示和建模3D空间中物体形状的方式。最常见的形式是有符号距离场（Signed Distance Fields，SDF），它通过神经网络来近似描述物体表面的位置。在这种表示中，每一个空间点都有一个标量值，表示到最近表面的距离。\n神经场的优势在于，它提供了一种连续的、差分可计算的方式来描述复杂的三维几何形状，相比于离散的表示（例如点云或网格），神经场在内存占用和计算效率上更具优势，且可以进行精确的表面重建。\n“姿态化”意味着神经场不仅表示物体的几何形状，还考虑了物体的位置和姿态（即其在三维空间中的方向和位置）。具体来说，NeuralFeels 中的神经场是通过优化物体的姿态（即物体在空间中的位置和朝向）和形状（即物体的几何特征）来动态更新和估计物体的模型。\n在NeuralFeels中，物体模型（即神经场）是通过交替优化的方式来估计的：\n形状优化：通过优化神经网络来更好地匹配物体的表面。\n姿态优化：通过优化姿态图（Pose Graph）来调整物体的相对位置和朝向，确保物体的表面与其姿态保持一致\n触觉相关 DIGIT视觉触觉传感器\n输入为触觉图像，输出为像素级深度图。\n前端 后端 需要讨论的问题 1 这个论文的代码里给的是原始的触觉输入图像，然后他们自己训了一个transformer来输出深度，如果用我们自己的传感器需要作哪些更改？\n2 SDF没有颜色信息，用GSDF转高斯？或者还有没有别的方法？从本质上来说，我只是需要物体的形状作监督，只是physgaussian和GIC等代码用的是颜色来作为损失，既然已经有SDF场，有没有什么办法能把sdf离散为粒子？比如sdf-\u0026gt;voxel-\u0026gt;particle\n补充材料 随便记录下\n物体的mesh和pose真值的获取 获取真实物体的mesh 获取真实物体的pose keyframe选取 两个指标，一个是时间间隔，另一个是将SDF渲染为深度图，与传感器深度图对比计算差异。若平均损失超过阈值 d_thresh？，说明当前SDF模型与观测数据差异较大（例如探测到物体新表面），从信息增益的角度出发？\n触觉-深度图相比于二值有哪些优势？ ","date":"2025-04-14T20:34:24+08:00","image":"https://Peraspera1.github.io/images/NeuralFeels/cover.png","permalink":"https://Peraspera1.github.io/p/neuralfeels/","title":"NeuralFeels"},{"content":"这个blog主要记录下我的一个idea， GIC + decoupledgaussian + 手物交互\n大致思路梳理 用灵巧手抓一个物体，输入抓取的视频，参考Decoupled Gaussian分离手物，再按照GIC的方式恢复物理属性。\n感觉代码主体框架应该建立在GIC的代码之上，先梳理下GIC的代码\n然后结合NeuralFeels和DecoupledGaussian\n感觉GIC的代码乱乱的，先看完吧，后续感觉NeuralFeels的结构更好，而且还是在线更新\nNeuralFeels输出的是SDF，如果需要接GIC，那么就需要转换为高斯，也就是说需要一个SDF转高斯的方法，这里需要去调研一下\n此外，如果是SDF场转换得到的高斯，是否还有必要过Decoupled Gaussian呢？\n应该先尝试跑通NeuralFeels的代码，工作量有点大\nGIC代码部分 NeuralFeels 代码部分 ","date":"2025-04-10T19:45:02+08:00","image":"https://Peraspera1.github.io/images/Replan1/cover.jpg","permalink":"https://Peraspera1.github.io/p/researchplan/","title":"ResearchPlan"},{"content":"","date":"2025-04-07T13:40:20+08:00","image":"https://Peraspera1.github.io/images/physgen3d/cover.png","permalink":"https://Peraspera1.github.io/p/physgen3d/","title":"Physgen3d"},{"content":"信息概览 论文题目： PhysTwin: Physics-Informed Reconstruction and Simulation of Deformable Objects from Videos\n论文单位： Columbia University\n是否开源： 是\n总结：\n这篇论文提出了一个名为 PhysTwin 的新方法，能够从仅有三视角的 RGB-D 视频中重建可变形物体的数字孪生体，并实现高保真外观还原与物理一致的动态模拟。其核心创新在于结合弹簧-质点物理模型、生成几何先验和高斯渲染，并通过稀疏到稠密的两阶段优化策略，在仅需一次交互数据的情况下，实现对物体几何、物理属性和动态行为的精确建模，支持未来状态预测、泛化到新动作以及实时交互仿真，显著提升了数据效率和实用性。\n论文思路 ","date":"2025-04-04T00:19:47+08:00","image":"https://Peraspera1.github.io/images/phystwin/cover.png","permalink":"https://Peraspera1.github.io/p/phystwin/","title":"Phystwin"},{"content":"论文信息 信息概览 CVPR 2025\n论文题目： Structured 3D Latents for Scalable and Versatile 3D Generation\n论文单位： THU\n是否开源： 是\n总结： 输入文本或图像，输出3D模型，并且有灵活的输出格式选择和本地 3D 编辑功能。\n论文细节\n结构化潜在表示（SLAT） SLAT 的核心思想是将3D资产的几何和外观信息编码为一个稀疏的3D网格 + 密集视觉特征的联合表示。具体设计如下：\n稀疏3D网格结构 定义：对3D资产$\\mathcal{O}$，定义一个分辨率为$N^3$（默认 $N=64$）的网格，仅标记与物体表面相交的“活跃体素”（active voxels），形成稀疏结构$\\{\\bm{p}_i\\}_{i=1}^L$（$L \\ll N^3$）。\n优势：稀疏性支持高效高分辨率建模，同时保留局部性（便于后续编辑）。\n局部潜在向量 每个活跃体素 $p_i$ 关联一个局部潜在向量 $z_i ∈ R^C$，用于编码该区域的几何和外观细节。\n特征来源：通过多视角渲染（150张随机视角图像），用预训练的 DINOv2 提取视觉特征，投影到体素并平均聚合，得到初始特征$ f_i$，再通过稀疏VAE编码为 $z_i$。\n编码与解码流程\n编码过程 视觉特征聚合 渲染多视角图像 → DINOv2 提取特征 → 投影到 3D 网格，生成稀疏特征 $f = {(f_i, p_i)}$。 稀疏VAE编码 使用基于 Transformer 的编码器 E，将 f 映射为结构化潜在空间变量 $z = {(z_i, p_i)}$。同时，输入的特征还会根据p加上一个正弦位置编码并进行序列化以便于输入到 网络中处理。 关键模块 3D Shifted Window Attention（Swin Transformer 这块我还没看懂），在稀疏体素间高效传递局部信息。 多格式解码 SLAT 支持通过不同解码器生成多种 3D 表示：\n3D高斯（DGS） 每个 $z_i$ 解码为 $K=32$ 个高斯球（位置、颜色、透明度等），通过体积渲染损失$（L1 + SSIM + LPIPS）$训练。 辐射场（DRF） 解码为局部辐射体积（CP分解形式），用类似损失优化。 网格（DM） 通过稀疏卷积上采样到 $256^3$，用 FlexiCubes 提取网格，基于深度/法线图损失训练。 训练策略 先以 3D 高斯为目标训练 VAE，再固定编码器，单独训练其他解码器。 两阶段生成模型 稀疏结构生成 目标：生成3D资产的稀疏体素结构 $\\{\\bm{p}_i\\}_{i=1}^L$\n输入：文本（CLIP特征）或图像（DINOv2特征）。\n模型：修正流变换器 $G_S$，生成低分辨率（$16^3$）的稠密特征网格$S$，解码为二值活跃体素网格$O$。\n先把随机初始化的稠密特征网络与位置编码并在一起，然后通过3D卷积VAE压缩为低分辨率特征$\\boldsymbol{S}\\in\\mathbb{R}^{16\\times16\\times16\\times8}$，在这个latent空间中去噪，条件是输入的文本或图片，之后将生成的 S 解码为稠密二值网格$\\boldsymbol{O}\\in\\{0,1\\}^{64\\times64\\times64}$，再转换为稀疏活跃体素 $\\{p_i\\}$。\n关键设计 使用 Conditional Flow Matching (CFM) 目标，优化噪声到数据的向量场。 $\\mathcal{L}_{CFM}(\\theta)=\\mathbb{E}_{t,\\boldsymbol{x}_0,\\boldsymbol{\\epsilon}}\\|\\boldsymbol{v}_{\\boldsymbol{\\theta}}(\\boldsymbol{x},t)-(\\boldsymbol{\\epsilon}-\\boldsymbol{x}_0)\\|_2^2.$\n引入 logit-Normal(1,1) 时间步采样，提升稳定性。\n局部潜在生成 输入：上一步的稀疏结构 ${p_i}$ + 条件提示。\n目标:为稀疏结构 $\\{\\boldsymbol{p}_i\\}$ 生成局部潜在向量 $\\{\\boldsymbol{z}_i\\}$\n模型：稀疏变换器 $G_L$，直接生成潜在向量 ${z_i}$。\n稀疏卷积下采样 将 64³ 体素打包为更短序列，提升效率。 跨注意力注入条件 文本/图像特征作为 Key-Value。 局部编辑能力 SLAT 的稀疏性和局部性天然支持灵活编辑：\n细节变体生成 固定稀疏结构，仅重新生成 ${z_i}$（通过新文本提示引导）。 区域特定编辑 指定编辑区域的边界框，结合 Repaint 策略：\n第一阶段：仅生成框内新结构。 第二阶段：生成框内细节，保持框外内容不变。 网络模型架构 3D-W-MHA: 3D窗口注意力机制 FFN：指任何前馈型的神经网络，可以有多个层，也可以没有隐藏层 MLP：是一种特定的 FFN，通常具有至少一层隐藏层，并且每层之间是全连接的\n论文结果 该方法与其他方法的对比\n重建质量的对比\n可视化结果对比\n更加细节的结果\n","date":"2025-04-02T12:01:01+08:00","image":"https://Peraspera1.github.io/images/SLAT/cover.png","permalink":"https://Peraspera1.github.io/p/slat/","title":"SLAT"},{"content":"论文总结 SceneMotifCoder SMC，一种基于示例驱动的视觉程序学习框架，用于根据文本描述生成3D物体排列。它利用大语言模型（LLMs）从少量示例中学习和概括空间图案，创建可重用的元程序，从而生成多样且物理上合理的3D布局。这篇文章之所以能够比其他方法在生成合理布局的方式上取得更好的效果，是因为他们显式地指定了物体排列的几种方式（比如堆叠，环绕，一共差不多10种左右），而且3D资产是从本地库里调出来的，比如输入一段话，模型会调用clip模型，找数据库里最符合的模型。\n这篇文章有几个很明显的缺点，首先motif/meta程序的生成需要不断地调用gpt做询问和验证，尽管论文中说3次以内GPT就能生成正确的程序，但是实测这一步极其容易失败，往往需要十几次迭代。其次，物体排列的方式一定得是他们提前规定好的那几种方式。第三，这篇文章主要是为了生成不同排列方式的Asset，但是Asset是从本地下载的资源库里得到的，而不是生成得到的，也就是模型资源有限，比如我想生成几本书堆叠在一起，往往一直都是那几本书。\ntrellis3d 利用了flow-matching等最新的大模型技术，加上大量的数据，做文/图生3D Asset，相比于以往的方法，能够生成更好的材质/细节等，在渲染质量上有了显著提升， 比较有意思的点是能有灵活的输出格式选择和本地 3D 编辑功能，\n一些最近工作与他的对比\n1 Hunyuan3D 2.0: Scaling Diffusion Models for High Resolution Textured 3D Assets Generation\n25.01.12\n这篇文章的baseline就是trellis3d；\n2 Simulating the Real World: A Unified Survey ofMultimodal Generative Model\n25.03.04\n一个综述，总结了下文字/图片生成3D Asset的一些工作，有张图我觉得还不错\n3 Amodal3R: Amodal 3D Reconstruction from Occluded 2D Images\n25.03.17\n在有遮挡的条件下重建3D物体\n4 Can Video Diffusion Model Reconstruct 4D Geometry?\n25.03.27\n动态场景的物体重建\n5 V2M4: 4D Mesh Animation Reconstruction from a Single Monocular Video\n25.03.11\n动态场景的物体重建，单目\n6 PhysTwin: Physics-Informed Reconstruction and Simulation of Deformable Objects from Videos\n25.03.17\n王申龙老师的工作，也cite了trellis3d，是我目前看到的最喜欢的工作！而且还开源了！\n为了应对稀疏观测带来的挑战，这篇工作利用了来自trellis3d和视觉基础模型的形状先验和运动估计来估计我们物理表示的拓扑、几何和物理参数。\nblender-mcp 两个星期前发布的，是一种利用 claude 控制建模的方式，和SMC类似。\nblender-mcp\n小结 主要介绍了3种不同的生成3D Asset的方法。\nSLAT 的核心目标是生成单个高保真3D物体（如一把椅子、一个杯子），专注于解决如何统一表示物体的几何形状和外观纹理。它通过隐式建模（如扩散模型）直接输出3D模型，支持多种格式（3D高斯、辐射场、网格）。\nSMC 的核心目标是生成多个物体的空间排列规则（如餐桌上的餐具布局、墙上的装饰画），专注于抽象化物体间的空间关系（如堆叠、环绕）。它通过程序化生成（如LLM编写的代码）描述物体如何摆放，依赖外部3D模型库实例化具体物体。\nSLAT 使用结构化潜在空间（稀疏3D网格 + 视觉特征）表示物体，通过两阶段扩散模型生成：首先生成稀疏结构，再填充局部细节。其优势在于高质量单物体生成，但编辑需通过隐变量调整，不够直观。SMC 使用视觉程序（如Python-like的领域特定语言）显式定义排列逻辑（如“循环放置5个盘子，间距0.1米”）。它通过LLM从少量示例中归纳程序模板，生成可读、可编辑的代码，直接控制物体位置、旋转和数量。\nSLAT 直接输出3D模型，但可能缺乏物理合理性（如物体悬空、穿透），需后处理修正。而SMC通过程序强制约束物理规则（如碰撞检测、接触面优化），生成布局更符合现实，但需依赖外部模型库和几何优化步骤。不过我感觉SLAT能够输出多种不同类型的3D模型，这是一个非常好的特点。\n其次，blender-mcp我感觉和SMC类似，这个方法的模型库来自一些网站（SMC是本地存储），但是总体来说，模型是固定的，但是这种方式的好处在于，通过claude调取网络上的模型库，其得到的模型资源会更加丰富一点，不过缺点显然就是没有那些物理上排列组合的约束。但是blender-mcp可以通过claude实时调整模型的位置，又稍稍弥补了这个缺点。个人体验而言，我觉得blender-mcp会更好一点。\nbtw，所有生成的模型都不能用于仿真，因为他们生成的都是表面的三角mesh，而物理仿真通常需要体网格（比如实心和空心的物体对于外力的响应显然是完全不同的）。其实想想也是，仅通过视觉怎么可能知道物体的内部结构呢？所以我认为才需要更多的信息帮助物体的重建，这样引入触觉就是非常自然的选择了。\n如果一定要用到上面的工作的话，我觉得只能用于碰撞检测吧，因为有生成的物体的几何外形之后，搞一个碰撞盒，做轨迹规划倒是可以，可以参考下面这篇论文。\nVISO-Grasp: Vision-Language Informed Spatial Object-centric 6-DoF Active View Planning and Grasping in Clutter and Invisibility\n25.03.17\n应该是iros25在投，感觉还可，在复杂场景抓取目标物体。\n一些物理仿真平台的调研和思考 Genesis 定位与特点： Genesis 是由 Taichi 和 Deepmind 共同推动的一个新兴开源物理仿真平台，本质上可以看作是对现有技术的高度集成与模块化重构。它底层使用 MuJoCo，结合 Taichi 进行高效并行计算，支持 GPU 加速，并引入光追模块用于渲染。\n优势：\n模块化强、拓展性好：得益于 Taichi 的参与，开发者可以方便地定制和拓展各类物理模块（如 MPM、PBD 等），特别适合研究者和算法开发者。\n对软体、流体友好：Taichi 提供的基础模拟能力，如 MPM 和 SPH，在处理可变形体和粒子系统方面很自然。\n可扩展的生成式接口潜力：虽然目前“生成式”这一方向尚未形成独特优势，但作为平台定位，未来潜力大。\n不足：\n底层依然依赖较老版本的 MuJoCo，动力学精度、接触建模等方面仍有提升空间。\n工业级应用生态尚未建立，稳定性与工具链配套较弱。\n算法实现多为基础版本，现阶段更适合作为研究原型平台。\n适用场景： 学术研究、软体/流体模拟原型、仿真平台开发、教学与原型验证。\n总结：\n我个人觉得Genesis的本质就是：mujoco底层+taichi+gpu并行+光追插件。东西都是之前熟悉并用过的东西，只是各取所长进行了一次重组，提高了开发效率。Genesis目前的taichi部分已经开放的软体和流体算法也只有很基础的mpm+，sph+，pbd+，都是20年taichi刚发布就有的东西，但之后说会有ipc可期待一波。使用体验上来说，目前Genesis的底层还是用的mujoco的旧引擎，对loco任务还好，但 manipulation抓取上还有问题，目前Genesis的优势主要在taichi方便的流体和可变形接口，如果要做软体的话，用这个平台会合适一点。\nGenesis最重要的贡献不是生成式，而是作为一个顶级开源仿真平台把这几年做的比较好的工作都集成到一起。尤其是对接taichi后，模块化好可拓展性很高，如果能做到持续维护更新的话会有很大的发展空间。\nissac sim Isaac Sim 由 NVIDIA 开发，基于 Omniverse 平台，具有极高的渲染质量。Isaac Sim 利用 RTX 光线追踪技术，实现逼真的实时渲染，是这三者中图形效果最强的工具，尤其适合需要高保真视觉数据的任务。\nIsaac Sim 采用 PhysX 引擎，这在游戏和高性能仿真中非常常见。其动力学求解支持高精度且实时的模拟，适合复杂的载荷和接触问题，且支持自定义物理参数和力矩输入。 但是物理建模虽然实用但不够“学术精确”，对于精细动力学建模（如复杂接触、软体力学）能力有限。 而且它的封闭性较强，底层不如 MuJoCo 和 Genesis 那样开放给研究者深度修改。\nissac lab就是基于issac sim开发的用于强化学习的benchmark\nmujoco MuJoCo 的渲染相对简单，主要用于计算物理仿真，因此图形渲染能力较为基础。它更注重物理仿真精度而非图形细节。\nMuJoCo 采用的是基于连续时间的动力学求解，使用优化方法进行求解，能够支持复杂关节和接触的高效仿真。它的物理引擎允许用户灵活定制载荷形式，可以在关节、链接和接触面上施加自定义力矩、阻尼等。\n如果要做强化学习，issac sim的并行训练效率更高，如果要做动力学仿真，mujoco的接触会非常准确，但是mujoco对软体、流体类任务支持有限，主要面向刚体系统。\n部分实验记录 先用smc生成了一个示例3D资产\n1 python inference.py --desc \u0026#34;a stack of four books\u0026#34; 这个资产在blender中打开，效果如下：\n感觉这个程序生成的资产有bug，一叠书里面只有部分书是有材质贴图的，应该是blender的问题，issac sim里是正常的。\n然后导入issac sim，首先简单验证了下碰撞等性质。\n","date":"2025-03-31T10:28:46+08:00","image":"https://Peraspera1.github.io/images/report0404/cover.jpg","permalink":"https://Peraspera1.github.io/p/report0404/","title":"Report0404"},{"content":"论文信息 信息概览 3DV 2025 Oral\n论文题目： SceneMotifCoder: Example-driven Visual Program Learning for Generating 3D Object Arrangements\n论文单位： Simon Fraser University\n是否开源： 是\n总结： 文生图，生成物理上合理的多对象排列，比如对于像堆叠的盘子或书籍排列等几何约束较强的物体。\n利用大型语言模型 （LLM） 的代码生成功能来创建可视化程序，以捕获常见 3D 对象排列的抽象。\n论文思路 问题的定义 网络输入一个自然语言的文本描述，描述了希望生成的3D物体布局。例如，一个文本描述可能是“在桌面上排列几本书，书的背面朝向相同”，或“堆叠几个盘子，每个盘子稍微偏离前一个盘子”。\n然后输出是一个3D物体布局，生成的布局根据输入的文本描述进行物体的排列和分布。这个布局是通过“视觉程序”表示的，通常包括了物体的位置信息、朝向、尺寸等细节。该布局必须符合文本描述的要求，同时保证物理可行性（例如避免物体重叠、确保平衡等）\n网络的训练 SMC的学习过程分为两个阶段：学习阶段和推理阶段。\n学习阶段 在学习阶段，SMC通过给定的物体布局示例来学习一个“motif程序”。 描述了物体的大小，位置等参数，不过这里的坐标，旋转都是与世界系对齐的，没有引入相对描述，例如“物体A放置在物体B的右侧”或“物体C的底部与物体D的顶部对齐”。\n首先，SMC从示例布局生成一个初步的程序$P_0$，这个程序可能会较为简单或不完全准确。\n然后，系统会根据这些示例优化程序，精炼出一个“motif程序”。这个程序可以描述物体如何在3D空间中排列。\n最终，程序会被推广为一个元程序（meta-program），这个元程序能够生成布局的多种变体。这使得系统能够从少量的示例中学习到更为普遍的排列规律，并能够在面对新任务时进行推理和生成。\n在这个过程中，SMC使用大语言模型（LLM）来生成和合成程序。程序的生成是通过逐步优化和学习来完成的，从而能够对输入的文本描述进行有效的映射。\nlearning框架\n代码测试\n输入数据 从\u0026quot;a stack of seven plates\u0026quot;这个glb模型出发，学习一个元程序\n1 python learn.py --file examples/a_stack_of_seven_plates.glb --desc \u0026#34;a stack of seven plates\u0026#34; 首先会加载保存的数据,比如这里是七个盘子，那就是七种mesh，然后还会从这七个盘子中挑一个盘子出来作为世界坐标系，这样其他盘子的网格坐标都会需要一个转换。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 def load_glb(file_path: str) -\u0026gt; tuple[gltf.GLTF2, list[Obj]]: \u0026#39;\u0026#39;\u0026#39; Load a glb file. Args: file_path: string, the path to the glb file Returns: glb_file: GLTF2, the glTF 2.0 file objs_in_file: list, the objects in the file \u0026#39;\u0026#39;\u0026#39; # TODO: Make less assumptions about the structure of the glTF file glb_file = gltf.GLTF2().load(file_path) objs_in_file: list[Obj] = [] # Load the main scene and the scene\u0026#39;s world nodes all_nodes = glb_file.nodes main_scene = glb_file.scenes[glb_file.scene] world_node_ids = main_scene.nodes # Load the objects in the world nodes for world_node_id in world_node_ids: main_node_ids = all_nodes[world_node_id].children # Load the objects in the main nodes # Each main node is a separate object for main_node_id in main_node_ids: main_node = all_nodes[main_node_id] # ----- Matrix ----- # Note: This logic is not general! # Assumes that the mesh_root_node has a matrix for the mesh # And the main_node has a matrix for placing the mesh in the world if main_node.matrix: main_node_matrix = np.array(main_node.matrix).reshape(4, 4, order=\u0026#34;F\u0026#34;) else: translation = main_node.translation if main_node.translation else [0, 0, 0] rotation = main_node.rotation if main_node.rotation else [1, 0, 0, 0] scale = main_node.scale if main_node.scale else [1, 1, 1] translation_matrix = trimesh.transformations.translation_matrix(translation) rotation_matrix = trimesh.transformations.quaternion_matrix(rotation) scale_matrix = np.diag(scale + [1]) main_node_matrix = translation_matrix @ rotation_matrix @ scale_matrix if len(main_node.children) \u0026gt; 0: mesh_root_node_matrix = all_nodes[main_node.children[0]].matrix if mesh_root_node_matrix is not None: mesh_root_node_matrix = np.array(mesh_root_node_matrix).reshape(4, 4, order=\u0026#34;F\u0026#34;) else: mesh_root_node_matrix = None # ----- Mesh ----- main_node_mesh = _load_all_meshes(glb_file, main_node) # Apply the mesh_root_node_matrix if it exists if mesh_root_node_matrix is not None: main_node_mesh.apply_transform(mesh_root_node_matrix) # ----- Bounding box ----- # Compute the oriented bounding box of the mesh centroid = main_node_mesh.bounding_box_oriented.centroid + main_node_matrix[:3, 3] half_size = main_node_mesh.bounding_box_oriented.extents / 2 main_node_bounding_box = BoundingBox(centroid, half_size, main_node_matrix[:3, :3]) # ----- Obj ----- # TODO: Allow the label to be provided separately label = main_node.extras[\u0026#34;semantics\u0026#34;][\u0026#34;label\u0026#34;] if \u0026#34;semantics\u0026#34; in main_node.extras else \u0026#34;unknown\u0026#34; obj = Obj(label, main_node_bounding_box, main_node_mesh, main_node_matrix) objs_in_file.append(obj) return glb_file, objs_in_file 生成naive的代码\n将一个 Arrangement 对象转换成一个 Program 对象。具体来说，它通过解析 Arrangement 中的每个 Object，并生成一系列代码，描述如何通过平移和旋转操作来创建这些对象并将它们放置到正确的位置和姿态。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 def from_arrangement(cls, arrangement: Arrangement) -\u0026gt; Program: \u0026#39;\u0026#39;\u0026#39; Create a program from an arrangement. Args: arrangement: Arrangement, an arrangement of objects Returns: program: Program, the program of the arrangement \u0026#39;\u0026#39;\u0026#39; code = [] code.append(\u0026#34;objs = []\u0026#34;) for i, obj in enumerate(arrangement.objs): label = obj.label centroid = obj.bounding_box.centroid.tolist() half_size = obj.bounding_box.half_size.tolist() coord_axes = obj.bounding_box.coord_axes # The object is initially aligned with the canonical coordinate system, so we need to rotate it to the correct orientation # For user convenience, the rotation operation is decomposed into three rotations around the x, y, and z axes # Here, we need to extract the three rotation angles needed to rotate the object to the correct orientation # In particular, we expect most objects only has a single rotation around the up axis (y axis), so we choose a rotation order of YXZ rotation_matrix = coord_axes y_angle = np.arctan2(rotation_matrix[0, 2], rotation_matrix[2, 2]) x_angle = np.arcsin(-rotation_matrix[1, 2]) z_angle = np.arctan2(rotation_matrix[1, 0], rotation_matrix[1, 1]) code.append(f\u0026#34;obj_{i+1}_half_size = {half_size}\u0026#34;) code.append(f\u0026#34;obj_{i+1}_centroid = {centroid}\u0026#34;) code.append(f\u0026#34;obj_{i+1} = create(\u0026#39;{label}\u0026#39;, obj_{i+1}_half_size)\u0026#34;) code.append(f\u0026#34;move(obj_{i+1}, obj_{i+1}_centroid[0], obj_{i+1}_centroid[1], obj_{i+1}_centroid[2])\u0026#34;) for axis, angle in [(\u0026#34;y\u0026#34;, y_angle), (\u0026#34;x\u0026#34;, x_angle), (\u0026#34;z\u0026#34;, z_angle)]: if abs(angle) \u0026gt; 1e-5: code.append(f\u0026#34;rotate(obj_{i+1}, \u0026#39;{axis}\u0026#39;, {np.rad2deg(angle).round(1)})\u0026#34;) code.append(f\u0026#34;objs.append(obj_{i+1})\u0026#34;) program = Program(code, arrangement.description) return program 对于上述输入的例子，结果为\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 Naive program: objs = [] obj_1_half_size = [0.08909, 0.0143, 0.08853] obj_1_centroid = [0.0, 0.0, 0.0] obj_1 = create(\u0026#39;plate\u0026#39;, obj_1_half_size) move(obj_1, obj_1_centroid[0], obj_1_centroid[1], obj_1_centroid[2]) objs.append(obj_1) obj_2_half_size = [0.08909, 0.0143, 0.08853] obj_2_centroid = [0.0, -0.00757, 0.0] obj_2 = create(\u0026#39;plate\u0026#39;, obj_2_half_size) move(obj_2, obj_2_centroid[0], obj_2_centroid[1], obj_2_centroid[2]) objs.append(obj_2) obj_3_half_size = [0.08909, 0.0143, 0.08853] obj_3_centroid = [0.0, -0.01514, 0.0] obj_3 = create(\u0026#39;plate\u0026#39;, obj_3_half_size) move(obj_3, obj_3_centroid[0], obj_3_centroid[1], obj_3_centroid[2]) objs.append(obj_3) obj_4_half_size = [0.08909, 0.0143, 0.08853] obj_4_centroid = [0.0, -0.02272, -0.0] obj_4 = create(\u0026#39;plate\u0026#39;, obj_4_half_size) move(obj_4, obj_4_centroid[0], obj_4_centroid[1], obj_4_centroid[2]) objs.append(obj_4) obj_5_half_size = [0.08909, 0.0143, 0.08853] obj_5_centroid = [0.0, -0.03029, -0.0] obj_5 = create(\u0026#39;plate\u0026#39;, obj_5_half_size) move(obj_5, obj_5_centroid[0], obj_5_centroid[1], obj_5_centroid[2]) objs.append(obj_5) obj_6_half_size = [0.08909, 0.0143, 0.08853] obj_6_centroid = [0.0, -0.03786, -0.0] obj_6 = create(\u0026#39;plate\u0026#39;, obj_6_half_size) move(obj_6, obj_6_centroid[0], obj_6_centroid[1], obj_6_centroid[2]) objs.append(obj_6) obj_7_half_size = [0.08909, 0.0143, 0.08853] obj_7_centroid = [0.0, -0.04544, 0.0] obj_7 = create(\u0026#39;plate\u0026#39;, obj_7_half_size) move(obj_7, obj_7_centroid[0], obj_7_centroid[1], obj_7_centroid[2]) objs.append(obj_7) high-level的观察\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def make_high_level_observations(llm_session: gpt.Session, naive_program: Program) -\u0026gt; None: \u0026#39;\u0026#39;\u0026#39; Prompt the LLM to make high level observations of the naive program. Args: llm_session: Session, the LLM session naive_program: Program, the naive program to observe Returns: None \u0026#39;\u0026#39;\u0026#39; llm_session.send(\u0026#34;optimize_highlevel_count\u0026#34;, {\u0026#34;program\u0026#34;: naive_program.code_string, \u0026#34;description\u0026#34;: naive_program.description}) llm_session.send(\u0026#34;optimize_highlevel_general_pattern\u0026#34;, {\u0026#34;description\u0026#34;: naive_program.description}) llm_session.send(\u0026#34;optimize_highlevel_xyz_pattern\u0026#34;) llm_session.send(\u0026#34;optimize_highlevel_xyz_displacements\u0026#34;) 比如给gpt的prompt是： \u0026lsquo;Below is a program about a spatial motif of \u0026ldquo;a stack of seven plates\u0026rdquo;. Describe how many object types and how many are there for each type. Respond with a json-like text structure with the object types as keys and the counts as values. Here is the program: （naive的程序）\n返回的结果如下：\n在有了high-level的观察之后，调用大语言模型（LLM）对一个排列描述（description）进行图案类型（motif type）分类，并确保分类结果是有效的。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 def classify_motif_type(llm_session: gpt.Session, description: str) -\u0026gt; str: \u0026#39;\u0026#39;\u0026#39; Prompt the LLM to classify the motif type of the description. Args: llm_session: Session, the LLM session description: string, the description of the arrangement Returns: motif_type: string, the classified motif type \u0026#39;\u0026#39;\u0026#39; with open(\u0026#34;motif_types.yaml\u0026#34;, \u0026#34;r\u0026#34;) as f: motif_types = yaml.safe_load(f)[\u0026#34;types\u0026#34;].keys() # ----- Validation function for this task ----- def classify_validation(response: str) -\u0026gt; tuple[bool, str, int]: motif_type = response.strip().lower() valid = motif_type in motif_types or (motif_type.startswith(\u0026#34;letter_\u0026#34;) and motif_type[-1] in \u0026#34;abcdefghijklmnopqrstuvwxyz\u0026#34;) error_message = f\u0026#34;The motif type \u0026#39;{motif_type}\u0026#39; is invalid. Valid motif types are: {motif_types}\u0026#34; if not valid else \u0026#34;\u0026#34; return valid, error_message, -1 # ----- End of validation function ----- motif_type = llm_session.send_with_validation(\u0026#34;classify\u0026#34;, {\u0026#34;description\u0026#34;: description}, classify_validation) return motif_type 也就说，物体的排列必须是以下几种排列之一。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 types: stack: multiple objects of the same type are placed orderly on top of each other pile: objects are placed on top of each other but not in an orderly manner (when in doubt between stack and pile, choose pile if the description contains the word \u0026#34;pile\u0026#34; explicitly) row: objects are placed next to each other in a row grid: objects are placed orderly in a grid, like a chessboard left_of: one object placed to the left of another object in_front_of: one object placed in front of another object on_top: one object placed on top of another object surround: objects are placed around a central object in a circular manner wall_vertical_column: objects are placed in a column from top to bottom vertically on a wall wall_horizontal_row: objects are placed in a row from left to right vertically on a wall wall_grid: objects are placed in a grid orderly and vertically on a wall (when in doubt between grid and wall_grid, choose wall_grid if the objects are placed on a wall) letter: objects are placed to form a letter of the alphabet rectangular_perimeter: objects are placed around the perimeter of a rectangular shape, facing inward 验证了物体排列合理性后，结合前文物体排序之类的信息，再去问gpt，优化出更高级的程序，比如之前naive的程序有7个create_plate，这一步会把该结构优化为for循环的结构，这样更加利于gpt捕捉空间中的高维结构。当然，还要验证gpt给出的代码是否满足这几个条件： （1） 无语法错误\n（2） 无硬编码的对象属性列表， （3） 每个标签的对象数相同，\n（4） 对象放置在相同位置，\n（5） 对象的缩放和方向相同。\n这一步极其容易报错。。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 def optimize_motif_program(llm_session: gpt.Session, naive_program: Program, example_arrangement: Arrangement) -\u0026gt; Program: \u0026#39;\u0026#39;\u0026#39; Prompt the LLM to optimize the naive program to create a motif program. Args: llm_session: Session, the LLM session naive_program: Program, the naive program to optimize example_arrangement: Arrangement, the example arrangement Returns: optimized_program: Program, the optimized motif program \u0026#39;\u0026#39;\u0026#39; # ----- Validation function for this task ----- def optimize_validation(response: str) -\u0026gt; tuple[bool, str, int]: program = gpt.extract_program(response, naive_program.description) validations = [ validator.validate_syntax, validator.validate_naive_listing, validator.validate_num_objects, validator.validate_centroids, validator.validate_bounding_boxes, ] arguments = [ [program], [program], [program, example_arrangement.objs], [program, example_arrangement.objs], [program, example_arrangement.objs], ] for i, (validation, argument) in enumerate(zip(validations, arguments)): valid, error_message = validation(*argument) if not valid: return valid, error_message, i return True, \u0026#34;\u0026#34;, -1 # ----- End of validation function ----- optimize_response = llm_session.send_with_validation(\u0026#34;optimize_lowlevel\u0026#34;, None, optimize_validation) optimized_program = gpt.extract_program(optimize_response, naive_program.description) return optimized_program 优化后的结果如下：\n1 2 3 4 5 6 objs = [] for i in range(7): plate = create(\u0026#39;plate\u0026#39;, [0.08909, 0.0143, 0.08853]) move(plate, 0.0, i * -0.00757, 0.0) objs.append(plate) # 仍然存储对象引用在objs列表中 此时，程序已经完成了从naive到motif的转变。然后还需要把motif的程序转换为meta的程序。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 def observe_commonalities_and_differences(llm_session: gpt.Session, motif_type: str) -\u0026gt; None: \u0026#39;\u0026#39;\u0026#39; Prompt the LLM to observe the high level commonalities and differences in programs of the same motif type. Args: llm_session: Session, the LLM session motif_type: string, the motif type Returns: None \u0026#39;\u0026#39;\u0026#39; # Get all programs of the same motif type all_programs = \u0026#34;\u0026#34; if library.length(motif_type) \u0026gt; 0: loaded_programs = library.load(motif_type) for i, program in enumerate(loaded_programs): all_programs += f\u0026#34;Program {i + 1}. \u0026#39;{program.description}\u0026#39;:\\n{program.code_string}\\n\\n\u0026#34; print(f\u0026#34;Loaded {len(loaded_programs)} programs of motif type: {motif_type}\\n\u0026#34;) else: raise RuntimeError(f\u0026#34;No programs in library for motif type: {motif_type}\u0026#34;) llm_session.send(\u0026#34;generalize_high_level_commonalities\u0026#34;, {\u0026#34;num_programs\u0026#34;: str(len(loaded_programs)), \u0026#34;motif_type\u0026#34;: motif_type, \u0026#34;all_programs\u0026#34;: all_programs}) llm_session.send(\u0026#34;generalize_high_level_differences\u0026#34;) llm_session.send(\u0026#34;generalize_high_level_motif_reason\u0026#34;, {\u0026#34;motif_type\u0026#34;: motif_type}) 上述程序的输出：\n1 2 3 4 5 6 7 8 9 10 11 12 ### Commonalities Across Programs: 1. **Consistent Use of the `create` Function**: Each program creates objects using the same type (e.g., \u0026#39;plate\u0026#39;) and size (e.g., `[0.08909, 0.0143, 0.08853]`). 2. **Modification of Object Positioning**: In all programs, object positioning is manipulated through the `move` function, typically modifying the coordinates along the primary axis of the motif (y-axis for stack, x-axis or z-axis for row/grid, and random offsets for pile). 3. **Consistency in Object Type and Size**: In each program variation, the same object type and size are used, maintaining a degree of consistency. 4. **Order and Spacing**: In most programs, objects are spaced with consistent intervals along the primary axis, although the spacing may vary (e.g., stack with a fixed offset, row with different spacing). ### Key Differences: - The key differences between programs revolve around how the objects are positioned: - A **stack** involves vertical alignment with consistent spacing. - A **row** involves horizontal alignment along one axis. - A **pile** involves random or unstructured placement, disrupting the uniformity. - A **grid** involves a two-dimensional arrangement, often across both x and y axes. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 def prepare_meta_program_info(llm_session: gpt.Session, motif_type: str) -\u0026gt; None: \u0026#39;\u0026#39;\u0026#39; Prompt the LLM to prepare information for writing the meta-program. Args: llm_session: Session, the LLM session motif_type: string, the motif type Returns: None \u0026#39;\u0026#39;\u0026#39; llm_session.send(\u0026#34;generalize_low_level_arguments\u0026#34;, {\u0026#34;motif_type\u0026#34;: motif_type}) llm_session.send(\u0026#34;generalize_low_level_structure\u0026#34;, {\u0026#34;motif_type\u0026#34;: motif_type}) def write_meta_program(llm_session: gpt.Session, motif_type: str, refine_comments: bool = True) -\u0026gt; Program: \u0026#39;\u0026#39;\u0026#39; Prompt the LLM to write the meta-program. Args: llm_session: Session, the LLM session motif_type: string, the motif type refine_comments: bool, whether to refine the comments of the meta-program Returns: meta_program: program, the written meta-program \u0026#39;\u0026#39;\u0026#39; # Get all programs of the same motif type if library.length(motif_type) \u0026gt; 0: loaded_programs = library.load(motif_type) else: raise RuntimeError(f\u0026#34;No programs in library for motif type: {motif_type}\u0026#34;) # Get the previous meta-program if available if library.length(motif_type, is_meta=True) \u0026gt; 0: past_meta_program = library.load(motif_type, is_meta=True)[0].code_string else: past_meta_program = \u0026#34;# NO PAST META-PROGRAM AVAILABLE\u0026#34; # ----- Validation function for this task ----- def generalize_validation(response: str) -\u0026gt; tuple[bool, str, int]: meta_program = gpt.extract_program(response, motif_type) batch_recreate_response = llm_session.send(\u0026#34;generalize_low_level_batch_recreate\u0026#34;) try: recreate_calls: dict[str, str] = json.loads(gpt.extract_json(batch_recreate_response)) recreate_calls = list(recreate_calls.values()) except json.JSONDecodeError as e: return False, f\u0026#34;Failed to decode the json response: {e}\u0026#34;, -1 valid, error_message = validator.validate_meta_program(meta_program, recreate_calls, loaded_programs) return valid, error_message, 0 if not valid else -1 # ----- End of validation function ----- generalize_response = llm_session.send_with_validation(\u0026#34;generalize_low_level\u0026#34;, {\u0026#34;motif_type\u0026#34;: motif_type, \u0026#34;past_meta_program\u0026#34;: past_meta_program}, generalize_validation) meta_program = gpt.extract_program(generalize_response, motif_type) # Refine the documentation of the meta-program if refine_comments: # ----- Validation function for this task ----- def refine_comments_validation(response: str) -\u0026gt; tuple[bool, str, int]: meta_program = gpt.extract_program(response, motif_type) valid, error_message = validator.validate_syntax(meta_program, require_objs=False) return valid, error_message, -1 # ----- End of validation function ----- refine_response = llm_session.send_with_validation(\u0026#34;generalize_refine_comments\u0026#34;, {\u0026#34;motif_type\u0026#34;: motif_type}, refine_comments_validation) meta_program = gpt.extract_program(refine_response, motif_type) return meta_program 其实上述步骤相当于就是一步步引导gpt写出正确代码的过程。对于这个例子，最后返回的示意meta程序是：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 def create_stack(num_objects, obj_type, obj_size, starting_position, vertical_spacing, rotation_angle=0, axis_alignment=\u0026#39;y\u0026#39;): \u0026#34;\u0026#34;\u0026#34; Creates a stack of objects based on the specified parameters. The objects are stacked along the given axis with consistent spacing between each object. Parameters: - num_objects (int): The number of objects to be created and stacked. For example, 7 for a stack of seven objects. - obj_type (str): The type of object to be created (e.g., \u0026#39;plate\u0026#39;, \u0026#39;cube\u0026#39;). Defines the kind of object to stack. - obj_size (list of floats): A list containing the half-size dimensions of the object in the x, y, and z directions. Example: [0.08909, 0.0143, 0.08853] for a plate. This defines the size of each object in the stack. - starting_position (list of floats): The initial [x, y, z] position of the first object. This sets the position of the bottom-most object in the stack. - vertical_spacing (float): The vertical displacement (in meters) between the centers of two consecutive objects in the stack. For example, `-0.00757` meters. - rotation_angle (float, optional): The rotation angle (in degrees) for each object around its local axis. Default is 0 (no rotation). This can be used if you need to rotate the objects around their axes. - axis_alignment (str, optional): The axis along which the objects will be stacked. Options are \u0026#39;x\u0026#39;, \u0026#39;y\u0026#39;, \u0026#39;z\u0026#39;. Default is \u0026#39;y\u0026#39;. For example, use \u0026#39;y\u0026#39; for vertical stacking, \u0026#39;x\u0026#39; for horizontal stacking along the x-axis, and \u0026#39;z\u0026#39; for stacking along the z-axis. Returns: - list: A list of all created objects that have been placed in the stack. The list contains the objects in the order they were stacked. Example call: create_stack(7, \u0026#39;plate\u0026#39;, [0.08909, 0.0143, 0.08853], [0.0, 0.0, 0.0], -0.00757) \u0026#34;\u0026#34;\u0026#34; objs = [] # Initialize an empty list to store the created objects # Loop to create and position each object in the stack for i in range(num_objects): # Create an object of the specified type with the given size obj = create(obj_type, obj_size) # Calculate the position based on the axis alignment and vertical spacing if axis_alignment == \u0026#39;y\u0026#39;: # For stacking along the y-axis (default) move(obj, starting_position[0], starting_position[1] + i * vertical_spacing, starting_position[2]) elif axis_alignment == \u0026#39;x\u0026#39;: # For stacking along the x-axis move(obj, starting_position[0] + i * vertical_spacing, starting_position[1], starting_position[2]) elif axis_alignment == \u0026#39;z\u0026#39;: # For stacking along the z-axis move(obj, starting_position[0], starting_position[1], starting_position[2] + i * vertical_spacing) # Apply rotation if provided if rotation_angle != 0: # Apply rotation around the x-axis by default rotate(obj, \u0026#39;x\u0026#39;, rotation_angle) # This could be modified to rotate around y or z if needed # Append the created object to the list of objects objs.append(obj) return objs # Return the list of objects that have been created and stacked 推理阶段 在推理阶段，给定一个新的文本描述，SMC首先从学习到的元程序库中检索出最合适的元程序。\n接着，应用该元程序生成相应的3D物体布局。这个布局生成的详细过程是，首先根据每个对象的标签和边界框尺寸从对象数据集中检索mesh，比如从数据集中检索四本书出来。\n检索的方式分为两种（这两种方式不能并行使用，论文中默认是第一种使用方法）：\n1 将该物体的包围盒（bounding box）与所有可用3D模型的尺寸进行对比。然后，根据尺寸差异对所有模型进行排序，从前五个最匹配的模型中随机选一个作为最终用于该物体的3D模型；\n2 基于语义描述和图像相似度匹配（使用CLIP模型），将每个物体的文本描述（例如“一个蓝色的陶瓷杯”）与一组3D模型的渲染图像进行对比。使用CLIP模型（如OpenCLIP）来计算描述与渲染图像之间的相似度得分，选择得分最高的模型作为物体的3D模型；\n然后问LLM，这四本书的旋转方向是否可以不同（下图的例子就是不一样的旋转）；\n然后元程序（例如 Stack(objects=[book1, book2, book3, book4])）会根据“堆叠”的规则来计算每本书在空间中的位置，这样就得到了一个初始的布局， 又因为book1本身就是一个glb文件了，所以可以把四个模型一起合成为glb文件。\n最后，为了避免物体之间出现穿透或悬空，SMC还会对整个场景执行一次几何优化，包括： 确保书与书之间正好接触；保持整体物理稳定性（比如最底下那本书不会“悬空”）；如果出现尺寸冲突，可能会微调物体间距或缩放某些物体。\n最后生成结果如下： 推理框架\n整体框架\n结果 输入同样的文本描述，SMC方法与其他文字生成模型的方法的对比。\n","date":"2025-03-28T13:13:17+08:00","image":"https://Peraspera1.github.io/images/SceneMotifCoder/cover.png","permalink":"https://Peraspera1.github.io/p/scenemotifcoder/","title":"SceneMotifCoder"},{"content":"之前提到的idea是在Physdreamer的基础上做分割，分割完了之后再在真实的场景上作预测和仿真。 最近突然发现今年的CVPR上有很多文章已经把我想做的事做完了，索性我就把今年CVPR里和我想做的领域相似的论文都看了一遍，并作了简短的总结如下，并在之后提出了一个新的idea。\nCVPR 2025 简要回顾 PACNerf (ICLR 2023 Notable) 开创性的工作，没有解决前景背景的分离，在现实世界中的仿真精度很低（体素表示的几何精度很低），需要手动设置材料的类别，然后优化得到材料的参数（简单解释一下，比如一个物体的重量是1kg,重量-类别；1kg-参数），但是可以作弹性仿真、粘性仿真等等；\nPieNerf (CVPR 2024) 优化了PACNerf在大扭曲情况下纹理失真的问题，缺点同PACNerf；\nPhysGaussian (CVPR 2024 Highlight) 开创性的工作 不能在现实中仿真，没有解决前景背景的分离，需要手动设置材料的类别+参数，只能作简单的弹性仿真；\nPhysDreamer (ECCV 2024 Oral) 在PhysGaussian上优化，用生成的视频作监督优化得到材料的参数，但是仍然需要手动设置材料的类别，其余缺点同PhysGaussian；\nVRGS (SIGGRAPH 2024) 在PhysGaussian 做了一个用户自定义施加力的功能，有简单的分割，其余缺点同上；\nPhysGen (ECCV 2024) 独立于上述工作，是二维平面的物理仿真，基本没有上述工作的缺点，利用大模型作材料预测，且二维的分割比较简单，但是只能做刚体模拟，连弹性仿真都做不了，但是二维平面的仿真上他们还可以设置材料的反光率等等，这点在三维环境中就比较难做了；\nGenerative Image Dynamics (CVPR 2024 Best Paper) 独立于上述工作，二维平面的可交互弹性仿真，无需显示指定材料，输入力，直接输出响应；\nDecoupledGaussian 论文题目：DecoupledGaussian: Object-Scene Decoupling for Physics-Based Interaction\n该工作的核心亮点在于分割\n此前所有的研究都无法保证前景与背景的完全分离，即使在2D空间上做了好的segmentation，也很难保证3D中点云的分割，而重建出精细的表面对于物理仿真相当重要，这篇工作的贡献点就在于：1 允许对象独立于初始接触表面移动;2 当物体和场景分离后，还能补全物体和场景的结构;\n效果如下： 整个框架如下: 首先还是传统的输入多视图图片+colmap+恢复高斯，然后将高斯分布压缩为与场景表面对齐的近似局部平面（这里具体的理论推导在PGSR中，不过我还没来得及仔细看）。PGSR就是压扁高斯点云（平面高斯），使其能正确对齐实际场景表面（不然可能出现浮动伪影）。而且被压扁的高斯优化更快速、稳定（只需要沿法线优化）。\n有了一层层平面的高斯之后，然后要识别哪些高斯点属于物体，哪些属于背景。\n具体来说，这篇文章是用语义特征分割的，即每个高斯点都会被赋予一个32维的特征向量，描述其在多视图（用于联合的优化）下的语义信息，然后再通过一个MLP（单层神经网络），将这些特征映射到不同类别（物体或场景）。这个具体实现的细节是一篇2024的ECCV Gaussian grouping 加2024年的SIGGRAPHVR-GS，本质上应该还是SAM，具体细节我也还没看。\n然后就是这篇文章最大的创新点，用Joint Poisson Fields同时恢复分离后物体和背景场景几何形态，灵感应该是来源于一篇13年的SIGGRAPH。 由于物体和背景在拍摄时是连接在一起的，因此在分离后，原本被遮挡的部分需要补全和修复。例如，一个花盆在桌子上，如果直接移除，桌面上可能会留下不平滑的痕迹，或者花盆底部会变形。\n文中的方法是同时计算计算物体的泊松指示函数$X_O$和背景的泊松指示函数$X_S$。如果 $X_{O(S)}(x)\u003e0.5$，表示该点属于物体（或背景）,如果泊松重建认为有的点同时属于物体和背景，那就直接当成背景，因为背景通常更加稳定。而且文章说Joint Poisson Fields自动生成平滑、封闭的3D表面？？？（例如，如果我们想要分离桌子上的一个花瓶，泊松重建会确保花瓶底部在分离后是封闭的，而不是一个空洞）\n其次，高斯点的$\\alpha$混合 (alpha blending) 可能导致多个高斯点的融合，真实表面的位置会受到影响，甚至出现几何扩展或重影，所以他们在现有高斯的基础上生成了代理高斯。\n具体来说，他们用了TSDF的方法，通过设置高斯点的$\\alpha$值，使得除了目标物体之外的所有高斯点透明，从而获得物体的二值掩码。设定一个 3D 体素网格。对于每个深度图 D(p)，计算 TSDF 值，并与已有的 TSDF 体素进行加权平均。V(x)，每个体素存储一个TSDF值。从TSDF体素网格中提取代理点(TSDF值从正变负的位置，代表物体的真实表面)，有了表面之后，再用一个他们自己的算法把之前的高斯插值到表面上的高斯，这个新的高斯就是代理高斯(proxy)。\n有了表面之后，还要做内部填充，不然做不了仿真（例如对于一个分离出的雕塑，我们需要在雕塑的内部填充粒子，使其不会在掉落时崩塌），文中的处理方法是在$X_{O}\u003e0.5$的泊松场区域内部提取密集粒子，当然这是因为Joint Poisson Fields能自动生成封闭的3D表面（虽然我不太理解为啥封闭，但是对于封闭的表面这样处理是合理的）。\n存在的问题\n论文有三个重要的算法，分别是PGSR，Joint Poisson Fields（泊松指示函数）和从TSDF表面得到代理高斯的算法，但是都没仔细介绍，所以我还需要仔细看看详细的理论推导过程。\n然后这篇文章本身存在的问题，首先这篇文章还没开源，没有代码，其次，那个多视图TSDF/物体掩码混合的过程需要将近100s，这个肯定可以优化，当然这篇工作还是为了重建精细的表面，才需要这个算法，而且对于时间其实没有太多的要求，然后这里的材料属性仍然需要手动设定。\nPhysFlow 论文题目：Unleashing the Potential of Multi-modal Foundation Models and Video Diffusion for 4D Dynamic Physical Scene Simulation\n该工作的核心亮点在于真实世界仿真+不需要手动设置材料参数\n整体框架如下： 思路简单地说就是在Physdreamer的基础上，把他们那个SDS loss改成了光流的loss，然后再仿照Phygens利用GPT设置材料属性。\n和之前的工作一样，先还是传统的输入多视图图片+colmap+恢复高斯，然后再是PGSR。 然后和Physdreamer不一样的是，Physdreamer只用了传统的SVD（图片生成视频），而这个模型多了个接口，还可以接（文+图）生视频等等各种生成模型。\n其余处理和Physdreamer一样，就是用PhysGaussian的方式，给定初始条件然后进行仿真，再用SVD生成的视频作监督，只是这个监督是光流的监督 ，就是在像素级别上让模拟出的运动轨迹（Î_t）与目标运动轨迹（I_t）尽可能接近，使用光流的好处是在大尺度的运动范围下，光流的监督相比于结构损失更加稳定，且计算开销小很多，等这个代码开源了我想去测一下计算开销。具体来说可以看下面这个图，PhysGaussian在模拟飞机螺旋桨的时候，螺旋桨会出现不自然的变形，这是因为PhysGaussian没有优化物理参数，而这篇文章用了能量最小化的物理约束进行优化，这个图就正常了很多。\n其次，Physdreamer只做了弹性情况的仿真，这个工作可以拓展到多种材料（一共七种：1弹性体: 杨氏模量𝐸和泊松比 𝜈；2塑性体: 𝐸,𝜈,屈服应力 𝜏 3金属: 𝐸,𝜈,屈服应力 𝜏；4泡沫: 𝐸,𝜈,塑性粘度 𝜂；5沙: 摩擦角 𝜃；6牛顿流体: 流体粘度 𝜇和体积模量 𝜅；7 非牛顿流体: 𝜇,𝜅,𝜏𝑌，η）。 因此他们大多数的数据都是和PACNerf作对比，但其实以上所有论文的仿真都是建立在胡渊鸣18年的那篇SIGGRAPH上的，理论上他们能做的场景physdreamer也能做，所以我觉得这个不能算是他们的创新点。\n不过有个关键的点文中没提，Physdreamer最重要的一点是生成视频的真实度有限，所以他们只取了视频的前8帧作监督，但是这篇工作并没有讲他们生成了多少帧视频来产生光流作监督， 只是说明光流的效果产生的效果物理真实感更强。其次，大部分的论文都是从视觉的角度去分析的，目前还没有人对胡渊鸣的那个物理仿真的代码做过优化（确实真正的物理仿真需要较多的精力去钻研），如果考虑机器手的操作倒是有可能有优化的方向。\nCVPR 2025 其余工作 1 DexGrasp Anything\n这篇文章昨天刚开源，该工作(DGA)用于通用机器人灵巧抓取。由于灵巧手高自由度和物体形态多样性，生成高质量抓取姿态具有挑战性。DGA通过表面拉力、外部渗透排斥力、自碰撞排斥力三种物理约束，在训练和采样过程中提升抓取的稳定性和合理性。此外，引入大语言模型（LLM）增强物体表征，结合3D点云和文本语义，提高对目标物体的理解。然后还做了一个数据集。\n2 Is Your World Simulator a Good Story Presenter? A Consecutive Events-Based Benchmark for Future Long Video Generation\n这个工作提出了StoryEval，一个专为文本生成视频模型设计的评测基准，用于衡量模型在事件连贯性、长视频生成方面的呈现能力\n3 LAYOUTVLM: Differentiable Optimization of 3D Layout via Vision-Language Models\n本文提出LayoutVLM，一种基于视觉-语言模型（VLMs）的3D布局生成方法，能够将未标注的3D资产按照自然语言指令生成物理可行（避免碰撞、越界）且语义合理（符合指令）的场景布局。\n4 Learning Physics From Video: Unsupervised Physical Parameter Estimation for Continuous Dynamical Systems\n通过分析视频中的物理运动来估计连续动力系统的参数，无需手动标注数据，不同于以往基于视频帧预测的方法，这个方法用Encoder将视频帧映射到Latent Space，得到动力学变量z。只在潜在空间中优化，提高训练稳定性和效率。鲁棒性强，但是目前应该只能解ODE方程（普通的微分方程），不知道能不能推广至数值求解。\n5 FluidNexus: 3D Fluid Reconstruction and Prediction from a Single Video\n这个工作应该是Jiajun Wu 和Zhu Bo(我本科导师的导师，主要领域是图形学和物理仿真)合作的工作，做单视频3D流体重建、未来预测和交互模拟。比较有意思的点是，他们采用两层粒子表示，同时进行物理模拟和渲染：物理粒子：基于PBF模拟流体的速度场和密度场。视觉粒子：基于3D高斯建模流体的视觉外观，并随物理粒子流动。感觉这是一个不错的idea，因为我之前尝试过让粒子同时携带高斯和物理属性，但是效果一直不好，他们的工作思路算是解决了我之前的疑问吧。不过他们还是用的生成模型做预测，可见流场的物理属性恢复与仿真目前还是挺有难度的。\n6 PhysAnimator: Physics-Guided Generative Cartoon Animation\n蒋陈凡夫他们组的工作，将静态动漫图像转换为风格化动画。这个工作其实和去年那篇CVPR best paper挺像的，但是可以模拟多种物理属性的物体。 7 PhysVLM: Enabling Visual Language Models to Understand Robotic Physical Reachability\n该研究提出了一种新型视觉语言模型（VLM）——PhysVLM，旨在提升机器人在执行任务时对自身物理可达性的理解能力。PhysVLM采用双分支架构，一部分用于视觉处理，另一部分用于处理S-P Map，并通过融合层将两者结合，以确保推理过程中既考虑视觉信息，又兼顾机器人物理约束。研究团队构建了一个大规模的多机器人数据集 Phys100K，并设计了 EQA-phys 基准测试来评估模型的性能。\n具体来说，假设有一个机器人，它的任务是从桌子上拿起一个薯片袋，然后放到一个碗里。传统的视觉语言模型看到这个场景后，可能会直接生成指令：“拿起薯片袋，放入碗中。” 但问题是，它并不了解机器人本身的物理可达性，也就是说，它不会考虑机器人是否真的能伸手够到薯片袋。PhysVLM 的改进在于，它引入了S-P Map（空间物理可达性映射），可以帮助模型理解机器人真正能够触及的范围。当PhysVLM观察到这个场景时，它不会直接给出“拿起薯片袋”的指令，而是会先判断薯片袋是否在机器人的可达范围内。如果它发现薯片袋超出了机器人手臂的极限，它会先建议：“移动机器人靠近薯片袋。” 在移动完成后，它才会生成下一步指令：“现在可以拿起薯片袋，并放入碗中。”\n感觉这个工作的思路挺清楚的，不过具体细节我还没看明白。框架如下：\n8 Physics-Based Full-Body Human Reaching and Grasping from Walking Data\n和上个工作有点像，这篇工作证明了简短的行走数据可用于生成多样化的抓取运动，有效降低数据采集成本，同时保证物理可行性和自然性，大致侧重于机器人的手脚协调、平衡调整。\n9 PhysicsGen: Can Generative Models Learn from Images to Predict Complex Physical Relations?(http://www.physics-gen.org.)\n和之前字节的那篇HOW FAR IS VIDEO GENERATION FROM WORLD MODEL: A PHYSICAL LAW PERSPECTIVE有点像，总而言之就是得出结论，目前的视频生成模型没有办法生成长时间的符合物理规律的视频，不过这篇工作的主要贡献点更多的是还是在数据集上吧。\n新的idea 因为上述CVPR一篇都没开源，所以我正在跑一篇GIC的工作，这篇工作是Neurips 2024的oral。\nGIC 论文题目：GIC: Gaussian-Informed Continuum for Physical Property Identification and Simulation\n输入一组多视图的图片以及已知的相机内外参数，目标是恢复出用连续粒子表示的物体几何外形和物理参数，是前几篇工作的集大成者，主要的创新在于物体内部粒子的填充。我最近准备看看这篇文章的细节和代码部分。\n整体框架如下： 总体来说，他们已经实现了用机器手实现简单的操作并同时恢复出物理属性，那么我的想法很简单，考虑用灵巧手去抓这个柔性物体，并同时实现物体物理属性的估计。 技术难点如下：1 首先此前所有的工作都基本未考虑遮挡情况下的物理属性恢复，但是灵巧手操作的时候肯定有遮挡，所以在有遮挡条件下进行物理属性的估计会比较难，不过有遮挡情况下的人手+刚性物体的表面重建老师应该比较懂；2 灵巧手与柔性物体的接触面积远比GIC的工作大得多，我希望能够和DecoupledGaussian结合一下，最好能够把不同时刻下的灵巧手和柔性物体的几何变化图分离出来；3 手物分离后，就可以单独对物体进行仿真，再按照PACNerf那种方式恢复物理属性；4 有了物体的几何表面和物理属性后，是否可以调整关节的角度/手指的位置？比如找一个failure case，传统的灵巧手去抓一个橡皮泥，用力太大，则橡皮泥的几何发生明显的变形从指间滑落，用力太小抓不起来之类的，不过这方面我的了解还不是很深入；\n反正我目前想先仔细地看看GIC的代码，然后把GIC作为baseline复现出来，再接到灵巧手上，先把硬件调通？然后不考虑强化学习、轨迹规划、触觉之类的，就先把物体放到灵巧手正下方，人工控制手执行抓取动作，做一个有遮挡条件下的物理属性恢复，或者直接用人手抓都行，不过我主要是想顺便趁这个机会学习下灵巧手硬件相关(ros)的东西所以有灵巧手更好；其余部分，比如怎么和VLA结合起来，怎么根据物体的属性调整手抓取的姿势和力之类的以后再说。\n上次的讨论结果 上周老师让我去测一下Physdreamer的运行时间，根据作者所说，在NVIDIA V100 GPU 需要花费1分钟来推理生成1s（24帧）的预测视频。这个代码对显存要求比较高，我还没跑起来，所以我就推测了一下，因为推理包含三个部分，分别是生成8帧的视频(在我自己的设备上大概需要20s，在他们的V100上应该更快)+渲染损失+仿真，而仿真的过程根据PhysGaussian的结果已经能够达到15~20FPS，那么大部分的时间都是花费在这个不断渲染损失并优化物理属性场的过程上，推测是40s左右。\n我找到了一篇文章 Simanything，里面有目前大部分文章的对比，结果如下：\n这个表格中PhysGaussian没有时间，是因为PhysGaussian是纯粹的仿真器，可以类比于神经网络的一次前向推理；而PhysDreamer没有时间，是因为他们认为训练SVD模型的时间很长，但PhysDreamer直接调用了已有的SVD模型，所以就没对比时间。\n这是这篇文章中和以前工作的一些对比：\n以及这篇工作的整体框架：\n这篇文章和DecoupledGaussian、PhysFlow一样都是投今年CVPR的工作，但是Simanything这个工作没中，我个人感觉原因可能有以下两点：1、Simanything 的分割做的不够好，而且他们的demo和DecoupledGaussian的demo一模一样，最后的效果一对比就被比下去了；2、他们文章中写的创新点是加速，但是他们之所以能够加速，首先他们用的是真实世界的视频输入作为监督信号，天然就比用生成视频的方式快；其次，他们用GPT-4V先预测了一个物理属性的均值，再去优化物体各个地方相对于均值的偏差，但是GPT-4V的输入是视觉信息（图片）+ 语言描述（BLIP）+ 语义匹配（CLIP），那么如果一开始GPT预测的属性已经很准了（大部分物体的物理属性在空间中的变化还是比较均匀的，比如一个物体的头部和底部的密度一般不会相差太大），那么优化自然会快很多很多，这个感觉完全可以通过调参数调出来。所以综合来看这篇工作的创新性不够，所以没中也是合理的。\n不过这篇文章可能用于参考的地方如下：\n他们描述了一张图片，然后输出了TOP-K个最需要预测的物理属性；那么迁移到机器人上，这个之前和金柯师兄讨论过，是不是就可能和VLA结合起来，输入一个动作（文本描述）+视觉信息（图片），输出执行该动作可能需要预测的物理属性之类的？\n之后准备做的工作 首先把GIC论文和代码的细节部分看完，等那些CVPR的工作的补充材料或者代码开源了之后我去仔细看看。\n然后有一些挺有趣的工作我也准备去看看。\n","date":"2025-03-18T13:35:13+08:00","image":"https://Peraspera1.github.io/images/report0318/cover.jpg","permalink":"https://Peraspera1.github.io/p/report0318/","title":"Report0318"},{"content":"论文信息 信息概览 NIPS 2024 Oral\n论文题目： GIC: Gaussian-Informed Continuum for Physical Property Identification and Simulation\n论文单位： The Hong Kong University of Science and Technology\n是否开源： 是\n总结：\n之前如PAC-NeRF采用NeRF表示隐式形状，几何精度不高，且在大变形下容易引入纹理扭曲，影响物理属性估计。 GIC使用3D高斯点云显式建模，通过运动分解学习动态形变，提升几何重建精度，同时提供更稳定的输入用于物理属性估计。\n从多视图视频中重建各种对象类型的几何形状和物理属性 假设：物体类型（例如，弹性、颗粒、牛顿/非牛顿、塑性）是已知的，并且物理现象遵循连续介质力学\n在机器人抓取场景下，GIC可用于识别真实物体的物理属性，实现虚实一致的变形模拟，为数字孪生提供了实际价值。\n目前还有哪些不足之处: 1 依赖于多视图输入和已知相机姿态：要求多视图视频和精确的相机内外参：\n2 系统不能自动识别材料种类，需要人为指定（如弹性、非牛顿流体等），降低了通用性\n3 模拟假设局限于连续介质：框架基于连续介质力学，难以处理断裂、分离等非连续变形现象。\n4计算资源消耗大：每个物体从几何重建到系统识别耗时约1.5小时，不适合实时或大规模部署。\n论文细节 背景知识 用传统高斯的方法渲染深度图和前景的mask，但是这里的高斯核是各项同性的，也就是协方差矩阵RS分解后的S是单位矩阵（为什么呢？）; 然后用splat的方式渲染每个视图下的深度，颜色，前景mask； 方法 目标还是，输入连续的视频，给定相机内参/外参，目标是重建物体的几何+物理属性\nmotion-factorized dynamic 3D Gaussian network\ncode ","date":"2025-03-17T20:43:53+08:00","image":"https://Peraspera1.github.io/images/GIC/cover.png","permalink":"https://Peraspera1.github.io/p/gic/","title":"GIC"},{"content":"这篇工作主要解决的是物体表面分离 在physgaussian的基础上\n相关论文 Vismay Modi, Nicholas Sharp, Or Perel, Shinjiro Sueda, and David IW Levin. Simplicits: Mesh-free, geometry-agnostic elastic simulation. ACM Transactions on Graphics (TOG), 43(4):1–11, 2024. 2\nYing Jiang, Chang Yu, Tianyi Xie, Xuan Li, Yutao Feng, Huamin Wang, Minchen Li, Henry Lau, Feng Gao, Yin Yang, et al. Vr-gs: A physical dynamics-aware interactive gaussian splatting system in virtual reality. In ACM SIGGRAPH 2024 Conference Papers, pages 1–1, 2024. 1, 2, 4, 5, 6,\n","date":"2025-03-15T20:32:40+08:00","image":"https://Peraspera1.github.io/images/decoupledgs/cover.png","permalink":"https://Peraspera1.github.io/p/decoupledgaussian/","title":"Decoupledgaussian"},{"content":"","date":"2025-03-14T19:07:36+08:00","image":"https://Peraspera1.github.io/images/simany/cover.png","permalink":"https://Peraspera1.github.io/p/simanything/","title":"Simany"},{"content":"Nvidia在今年一月份发布的工作Cosmos是目前较为先进的视频生成模型，而且文中还专门提到了他们有很多操作相关的数据。 我尝试了下这个模型，工作流如下： 生成1280*704的视频，长度为5秒，部分结果如下：\n可以看出，当前模型的效果并不理想。在光影变化和广角视觉效果方面，它已经做得相当不错，能够呈现出较好的视觉效果。然而，在物理场模拟上仍存在明显不足，尤其是在处理流体、爆炸等高度非线性或具有剧烈突变的场景时，表现尤为欠缺。\n第二篇工作是Physdreamer，是在PhysGaussian的基础上做的。\nPhysGaussian是第一篇将3D高斯核（用于渲染）与物理属性（如速度、应变、应力）相结合，使其能够模拟牛顿力学中的动态行为，适用于多种不同材料（如弹性物体、金属、非牛顿流体等），但是这篇工作需要手动地设置物理系数，而且输入的是3DGS输出的高斯表示（论文中是用手机拍照，接入colmap恢复点云，再接入3DGS）\n论文的关键思想是生成运动中物体的合理demo，比如一朵花，他把花离散为很多稠密的点，但这些点不是同构的，因此每个点的杨氏模量都不一样，然后按照物理属性去优化材质场E以匹配这个合成的运动。 我们首先从某个视点为 3D 场景出发渲染静态图像。然后，我们利用图像到视频模型(SVD)生成一个短视频剪辑 {$I_0$， $I_1$， . . . ， $I_T$ }，描绘对象的真实运动，这个生成的模型是GT来监督模拟得到的图像，然后再通过可微分模拟和可微渲染来优化材料场E(x)和初始速度场$v_0$(x)，使得模拟的渲染视频与生成的视频匹配。 但其实我觉得核心的部分还是图中下面的箭头，也就是PhysGaussian的工作比较重要。\n","date":"2025-03-11T20:35:54+08:00","permalink":"https://Peraspera1.github.io/p/report0312/","title":"Report0312"},{"content":"随笔 动画模拟\n","date":"2025-03-11T14:46:34+08:00","image":"https://Peraspera1.github.io/images/physanimator/cover.png","permalink":"https://Peraspera1.github.io/p/physanimator/","title":"PhysAnimator"},{"content":"这篇文章主要总结了下Jiajun Wu他们组有关物理感知/机器人相关的工作，还有些近期的工作，与summary1部分内容相同。\nJiajun Wu 工作 Galileo: Perceiving Physical Object Properties by Integrating a Physics Engine with Deep Learning\n2015 NeurIPS\n只能输入初始的静态的位置，对一维的摩擦力+动量守恒的规律建模\nLearning to See Physics via Visual De-animation\n2017 NeurIPS(Spotlight)\n输入三张图片，两两之间测量速度，预测二维平面上的动量守恒\nPhysical Primitive Decomposition\n2018 ECCV\n人们用锤子敲击物体的时候会拿起锤子的柄而非锤子的头，那么当机器人去操作的时候应该如何让它知道这个信息呢？\nSee, feel, act: Hierarchical learning for complex manipulation skills with multisensory fusion\n2019 Science Robotics\nLearning Physical Graph Representations from Visual Scenes\n2020 NeurIPS(Oral)\nUnsupervised Segmentation in Real-World Images via Spelke Object Inference\n2022 ECCV(Oral)\n对真实世界中的物体进行分割\nDifferentiable Physics Simulation of Dynamics-Augmented Neural Objects\n2023 RAL\nPhysically Grounded Vision-Language Models for Robotic Manipulation\n2024 ICRA\n近期的一些实验 上次提到了Physdreamer，这应该算是Jiajun组里最新的结果了，简而言之就是给定视频的初始帧，利用生成模型生成视频中物体未来的动作，再用这个生成的结果作为监督信号优化物理场。优点是只需要一张图片作为输入，缺点是生成的视频不符合物理规律。如果考虑到实际机器人的操作的话，其实没必要像他们那样用生成的方式，而应该是比如说机器手自主探索环境中物体受力的影响，学习到一些信息后再进行操作。\n而且我个人觉得视频生成模型在富含物理规律的生成方面做得并不够好，比如Nvidia在今年一月份发布的工作Cosmos应该可以代表目前最强的视频生成模型了（因为堆了很多数据），而且文中还专门提到了他们有很多操作相关的数据。 我尝试了下这个模型，工作流如下： 生成1280*704的视频，长度为5秒，部分结果如下：\n可以看出，当前模型的效果并不理想。在光影变化和广角视觉效果方面，它已经做得相当不错，能够呈现出较好的视觉效果。然而，在物理场模拟上仍存在明显不足，尤其是在处理流体、爆炸等高度非线性或具有剧烈突变的场景时，表现尤为欠缺。\n我认为其中一个关键原因是物理属性的分布方式与像素空间中色彩的分布方式截然不同。色彩在像素空间中的分布通常可以近似为独立同分布（IID），而物理系统中的变量往往存在高度的相互依赖性和因果性。又想到目前许多灵巧手的研究正在采用扩散模型（Diffusion Models）来生成操作轨迹。然而，本质上，这种方法与视频生成的思想是相同的——它依赖于统计概率的相关性，而非物理上的因果律。具体来说，这些模型通常通过学习帧与帧之间的统计相关性，来预测并生成轨迹。但这种方法并不直接考虑物理系统的动力学约束，而是基于数据驱动的方式，在高维概率分布中寻找模式。这类似于视频生成模型如何学习帧与帧或像素之间的关联，而非物理世界中光线传播的真实物理机制。然而，物理系统的演化不仅仅是一个统计问题，更是因果驱动的——例如，在流体动力学、刚体碰撞或柔性物体操作中，每一个状态的变化都严格受偏微分方程或其他物理定律约束，而不是简单的统计相关性。\n从这个角度来看，单纯依靠扩散模型生成轨迹，短期内可能在数据拟合上表现不错，但从长期来看，缺乏对物理约束的精确刻画，难以真正提升灵巧手的操作能力。这也是物理仿真不可或缺的原因之一——它能够提供真实的物理约束，使生成的轨迹不仅在统计上合理，而且符合物理因果关系，从而提升机器人操作的可靠性和可推广性。\n部分理论解释 一些比较精彩的解释bySora物理悖谬的几何解释(这里还有很多理论我还没看明白，之后多去学习一下)\n为什么数据点云是低维的，而非占满整个原始数据空间？ 因为自然现象满足大量的自然规律，这些规律的限制降低了数据样本点云的维数，而无法占满整个空间。比如，我们考察所有自然人脸照片构成的数据集，每个采样点是一张图片，像素的个数乘以3就是原始图像空间的维数。原始图像空间中的任意一点，都是一幅图片，但是极少的图片才是人脸图片，才会落在人脸图片流形上，因此人脸图片流形不可能占满整个原始图像空间。人脸需要满足很多自然的生理学规律，每个规律都会降低数据流形的维数，例如左右对称，就减少了近一半的像素，都有五官等确定的几何与纹理区域，每个器官的形状类似，描述的参数不多，因此进一步降低维数。最终控制人脸的基因非常有限，由此人脸图片流形的维数远远低于图片像素个数。再如，我们观察平面区域的稳恒态温度分布，由物理热扩散定理，稳定函数满足经典的Laplace方程，由其边界值所唯一确定。如果我们在区域内部有n平方个采样点，在区域边界有n个采样点，那么每个观察到的温度函数被表示为维数为n平方的向量，即原始数据空间维数为n平方，但是实际的流形维数为边界函数的维数n。由此可见，满足物理定律的观察样本构成的数据流形维数远远低于原始数据空间维数。\n为什么点云集合是流形，即局部是连续光滑的？ 绝大多数情形下，物理系统是适定的，但在临界状态下，物理系统会发生突变（由灾变理论或者临界态理论来描述）。物理定律多由偏微分方程系统来描述，微分方程的解由初始值和边界值来控制，系统是适定的，意味着由于能量守恒、质量守恒、能量传递小于光速等物理限制，初边值逐渐变化时，解也随之逐渐变化。在偏微分方程的正则性理论中，这意味着边值的索伯列夫范数控制解的索伯列夫范等等。我们将解视为数据流形上的点，边值视为其对应的局部坐标（即隐空间中的对应隐特征向量）。从数据流形到隐空间的映射被称为是编码映射，从隐空间到数据流形的映射被称为是解码映射。正则性理论保证编码映射和解码映射是连续的乃至光滑的，解的唯一性保证这些映射是拓扑同胚或者微分同胚。边值可以任意局部扰动，即隐变量存在一个开欧式圆盘的邻域。这意味着满足特定物理定则的观察样本构成了数据流形。\n数据流形上的概率分布如何表示？ 关于第三个问题的回答是：用传输变换，将数据概率分布变成计算机可以生成的高斯分布。这个传输变换可以在原始数据空间中进行，也可以在隐空间中进行。常用的传输变换包括最优传输变换和热扩散。我们用流体力学的观点来解释。假设整个隐空间是一个水箱，里面有某种溶剂，其密度为概率密度。我们扰动水箱，使得液体流动起来，使得溶剂密度发生变化。我们计算每个水分子的流向和流速，使得概率密度的熵一直增加，最后就得到高斯分布。例如，我们考虑人脸数据分布，这里每个水分子就是一张人脸图片。我们为人脸图片不断添加噪声，得到一系列图片，直至变成一张白噪声图片。这一系列图片就是水分子的运动轨迹。最后每张人脸图片变成白噪声，所有这些白噪声分布满足高斯分布。这一过程被称为是郎之万的动力学。反过来，给定一张白噪声，我们沿着水分子轨迹倒溯源头，就得到一张人脸图片。这就是扩散生成模型的原理（diffusion model）。当然，也可以直接用最优传输理论求解隐空间到自身的同胚，将数据分布变成高斯分布，这需要求解蒙日-安培方程。由此可见，数据分布的所有信息都由传输映射所包含，而传输映射被一个深度网络来表达。\n在Sora生成的视频中，每一帧都异常逼真，但是当老奶奶吹了生日蜡烛的时候，蜡烛的火苗纹丝不动。如果我们将视野缩小到每一个令牌的区域，我们看到美轮美奂的真实画面，令牌之间的衔接也非常平滑自然，但是当相距较远的令牌之间有因果联系的时候，即吹出的空气影响火苗的跳动时，两个令牌之间的物理因果没有体现出来。这意味着Transformer用以表达令牌之间的统计相关性，无法精确表达物理因果律。虽然transformer可以在一定程度上操纵自然语言，但自然语言无法准确表达物理定律，而物理定律目前只有偏微分方程才能精密表达。这反应了基于概率的世界模型的某种局限性。\n自然界的绝大多数物理过程都是稳恒态与临界态的交替变化。在稳恒态中，系统参数缓慢变化，容易获取观察数据；在临界态中（灾变态），系统骤然突变，令人猝不及防，很难抓拍到观察数据。因此，临界态的数据样本非常稀少，几乎在训练集中零测度。由此，Sora系统学习到的数据流形，绝大多数都是由稳恒态的样本所构成。物理过程中的临界态样本多分布在数据流形的边界。因此，在生成过程中，Sora非常容易生成稳恒态的视频片段，但是往往跳过临界态。但是在人类认知中，最为关键的观察恰恰是概率几乎为零的临界态。\n","date":"2025-03-10T21:29:30+08:00","image":"https://Peraspera1.github.io/images/summary_cover2.jpg","permalink":"https://Peraspera1.github.io/p/physic_summary2/","title":"Physics_Summary2"},{"content":"论文信息 信息概览 NeurIPS 2015\n论文题目： Galileo: Perceiving Physical Object Properties by Integrating a Physics Engine with Deep Learning\n论文单位： MIT\n是否开源： 否\n总结： 斜坡实验，视觉输入推断物体在动态场景中的物理属性（摩擦力+动量守恒）\n论文细节 小记 估计物体的质量、位置、3D 形状和摩擦力\nmapping visual inputs to physical properties\n看到物体从坡道上滑下、相互碰撞、滚动、进入其他物体、坠落 — 不同质量、材料和其他物理特性的物体之间的多种物理相互作用\n人类利用逼真的物理引擎作为生成模型的一部分来解释现实世界的物理场景\n这个模型有三个部分，\n第一个部分是生成对象的物理表示（刚体表示：形状+质量+摩擦力[没有速度吗？]），根据视觉输入进行近似或估计。\n第二个部分是在Bullet的基础上，这个引擎输入上述的物理表示然后执行前向的物理模拟，算出模拟得到的速度和位置曲线。\n第三部分是似然函数？用场景中的速度矢量来评估真实世界的视频？？\nNow, given a video as observation to the model, physical scene understanding in the model corresponds to inverting the generative model by probabilistic inference to recover the underlying physical object properties in the scene.\nnone of them focused on learning physical properties directly, and nor they have incorporated a physics engine with representation learning.\n一个物体从倾斜的表面上滑下来，并可能与地面上的另一个物体发生碰撞。\n将物理引擎的反馈合并到循环中，从视觉输入中估计物体的物理属性。\n首先，我们提出了 Galileo，这是一种新颖的模型，通过将物理引擎的反馈合并到循环中，从视觉输入中估计物体的物理属性。我们证明，它在真实世界的视频数据集上取得了令人鼓舞的性能。其次，我们训练一个基于深度学习的识别模型，该模型可以在生成模型中进行高效推理，并使生成模型能够预测静态场景的未来动态演变（例如，该场景如何及时展开）。第三，我们测试我们的模型，并将其与人类在各种物理判断任务上进行比较。我们的结果表明，人类在这些任务中非常成功，我们的模型在性能上与人类非常匹配，但也始终犯与人类类似的错误，这为支持人类物理场景理解的概率模拟解释提供了进一步的证据。\n训练的网络是LeNet 输入裁剪好的图像块，输出物体的label（属性）\n","date":"2025-03-10T15:32:44+08:00","image":"https://Peraspera1.github.io/images/galileo/cover.png","permalink":"https://Peraspera1.github.io/p/galileo/","title":"Galileo"},{"content":"论文信息 信息概览 Science Robotic 2019\n论文题目： See, feel, act: Hierarchical learning for complex manipulation skills with multisensory fusion\n论文单位： MIT\n是否开源： 否\n总结：\n文章要解决的一个核心问题是机器人如何像人类一样，结合视觉和触觉信息，高效学习复杂的物理操作技能，比如玩 Jenga（叠叠乐）？\n论文细节 分析： 这个问题可以从两个角度来解读：1 机器人需要边操作边感知，用触觉和视觉来推测积木状态，而不是仅靠视觉；2 机器人需要同时处理可移动和不可移动的积木，制定合适的策略来提取积木，而不让塔倒塌。传统机器人学习主要依赖视觉数据，缺乏触觉推理能力，导致它们需要大量数据才能学会基本操作。而基于强化学习方法需要大量训练数据，但由于Jenga游戏中的物理交互细节微妙，RL难以快速收敛。因此，文中给出的方法可以按照探索（Exploration）+ 学习（Learning）+ 决策（Decision Making）的框架来解决。\n探索 机器人随机选择一个积木并执行推的动作，并记录：积木的受力情况（触觉传感器），积木移动的位置和角度（摄像头），机器人末端执行器的参数（本体感知），塔的稳定性（由视觉观测），类似于人类玩Jenga时会试探性地推一下积木，看看它是否松动\n训练 论文提出了一种分层学习（hierarchical learning）方法；\n低层级：学习物理参数（如积木的受力情况、摩擦力、位移）\n高层级：归纳行为模式（如“积木可以移动” vs “积木被卡住”）\n绿色集群表示机器人未与任何块接触的轨迹，特别是在轨迹开始时，测得的力可以忽略不计，并且块不会移动。灰色簇表示抵抗运动并被卡住的块，表现出较大的阻力并且几乎没有平移。蓝色簇表示相当容易移动的块（大位移）并且表现出可以忽略不计的阻力。黄色集群表示移动但对机器人提供有意义阻力的块。\n计算：积木是否容易被推动（基于力反馈）/积木是否松动（基于历史数据）/积木移动时的可能路径（基于视觉+力传感器）\n论文使用了贝叶斯神经网络（BNN, Bayesian Neural Network） 学习积木的力学行为模式，使机器人可以从少量数据中泛化：输入：推积木时的力+位移信息。输出：预测未来的受力情况和积木的运动轨迹。\n泛化 机器人在每次推积木时，会先计算成功的概率。例如，如果积木之前被推过但没有动，机器人会降低推的力度或改变推的方向。\n然后执行贝叶斯更新（Bayesian Update）：机器人会随着每次操作更新对积木状态的信心。\n例如：机器人发现某个积木很难移动 → 更新其状态为“卡住”，减少未来的尝试。发现某个积木容易移动 → 优先尝试此类积木。\n更多训练的细节： 1 采用贝叶斯建模学习积木的物理属性； 2 用深度学习训练一个预测模型（输入力，预测积木的反应）； 3 机器人自监督学习，不断改进对积木状态的推测；\n思考 这个训练的框架也许有用，但应该仅限于摩擦力的框架，而且我对BNN并不太了解；\n估计摩擦力的框架到时可以借鉴？即输入物体的rgb图+末端执行器的位姿+施加力的大小和方向，然后先算一步先验(即初步估计的摩擦系数，就能简单的判断这个力是否能推动物体)再输入神经网络，得到物体下一时刻的位移。\n其他 论文提出了一种分层学习（hierarchical learning）方法，通过视觉和触觉融合，使机器人学习Jenga游戏中的操作技能\n论文想要解决的问题是主动感知与混合行为。\n首先是如何通过视觉信息和触觉信息来感知世界； 然后是如何通过多模态信息来学习操作；\n基于RL构建的大部分方法都无法有效地利用利用有关对象和动作的物理知识，而且这些系统需要比人类多得多的训练数据来学习新模型或新任务，而且它们的泛化范围要小得多，鲁棒性也要差得多。\n给机器人的任务是玩Jenga这个游戏。\n对于这个任务，人类通过触摸积木并结合触觉和视觉感官来推断它们的交互来获取信息\n基于此，机器人通过视觉信息来学习有关塔的位置和当前区块排列的信息。\n以抽取的木条的数量作为评价指标；\n机器人知道每一个时间步下的机械手的位姿，物体的姿势和施加到物体上的力\n很多仿真系统中对于摩擦力的建模是很粗糙的，因此仿真到现实的gap是难以弥合的。\n触觉信息是间断的，很难与视觉信息对齐。在Jenga任务中，视觉信息和触觉信息互相补充。\n触觉反馈可以提供高分辨率的局部信息，以补充来自视觉的全局但粗略的信息。\n","date":"2025-03-08T14:43:57+08:00","image":"https://Peraspera1.github.io/images/SFA/cover.png","permalink":"https://Peraspera1.github.io/p/sfa/","title":"SFA"},{"content":"论文信息 信息概览 ECCV 2024\n论文题目： DoughNet: A Visual Predictive Model for Topological Manipulation of Deformable Objects\n论文单位： Columbia University\n是否开源： 是\n总结： 纯视觉的预测模型，主要用于长时间预测可变性物体(如黏土/橡皮泥)的在不同物理条件下的几何拓扑变换。 可变形物体（如面团）的操作通常涉及拓扑变化（如分裂、合并）。传统方法主要关注几何形变，而忽略了拓扑变化。为了解决这个问题，研究者提出 DoughNet，一个基于 Transformer 的视觉预测模型，能够推测因不同工具或操作方式导致的拓扑变化。\n论文细节 输入输出 DoughNet 需要三个主要输入：\n初始状态的 RGB-D 图像：通过深度相机（如RealSense）获取点云数据。 由于是单视角，数据是不完整的，因此需要进一步补全。\n机器人端执行工具（End-Effector, EE）的几何形状： EE 可以是剪刀、夹子、滚轴等工具，每种工具会对物体施加不同影响。 该工具的几何形状以点云形式输入。\n操作轨迹（Action Trajectory）：机器人执行的操作，包括工具的移动路径、开合角度、力的大小等。\nDoughNet通过潜在空间预测生成两个核心输出：\n1 几何预测（Geometrical Prediction）：\n预测物体的形状变化（如被拉长、压扁、弯曲等）。 结果以点云、体素或隐式表面表示（Occupancy Map） 输出。\n2 拓扑预测（Topological Prediction）：\n预测物体是否会合并、分裂或变形为不同拓扑结构（如从球变为环）。 结果以拓扑图（Topology Graph）形式表示，包括：连通组件数量（Number of Components），每个组件的拓扑属性（如 genus, 环数）。 这些输出最终用于机器人操作规划，帮助选择合适的工具和动作策略。\nfor example,输入：初始面团形态（RGB-D 图像）;给定机器人工具为刀片；再给一段向下切割的轨迹。 那么这个网络会预测切割过程中的形态变化（面团从整体到分裂）及最终分裂后的面团形态（两个独立部分）\n网络信息流 编码 DoughNet采用去噪自编码器来处理输入数据，并生成潜在表示（Latent Codes）。\n首先对于物体的初始点云数据 $X \\in ℝ^{N×(3+1)}$（XYZ 位置 + 深度值）。使用Transformer Cross-Attention 计算点云之间的关系，并生成一组潜在特征（Latent Codes）。 再使用自注意力机制（Self-Attention）在点云上执行全局聚合，生成一个紧凑的潜在编码（Z）。这个潜在编码允许 DoughNet 处理不同大小和拓扑结构的物体。\n然后把EE（工具）的几何信息也被编码成潜在向量，与物体的潜在表示一起处理，以推测它们的交互方式。\n输出：一组潜在编码 [z]，表示物体当前的形状及拓扑信息。\n预测 DoughNet采用自回归预测来模拟物体在操作过程中的变化。\n输入：\n物体当前的潜在编码 [zt]。\nEE 的编码 [zt_m]，代表操作工具的信息。\n当前的操作 [a_t]（如 EE 移动路径）。\nTransformer 预测:\n通过Cross-Attention，模型推测物体与 EE 交互后下一步的潜在编码 [z_{t+1}]。 由于预测发生在潜在空间（Latent Space），计算量较低，且模型可以学习更稳定的特征。\n多步预测（Multi-Step Prediction）：\n由于是自回归结构，DoughNet可以递归地预测未来形态（反复输入自己的输出，进行多步预测）。\n预测的输出是： 1 下一步物体的潜在编码 [z_{t+1}]。 2 EE 的影响 [z_{t+1}^m]（用于判断 EE 选择是否合理）。\n解码 DoughNet 需要将预测的潜在编码转换回物体的几何形状和拓扑结构。\n形状解码：采用 Transformer 解码层，将潜在编码 [z] 还原成 物体表面的点云或体素网格。\n组件分割（Component Segmentation）：预测哪些点属于哪个物体组件（如两个面团是否仍然是一个整体，或已经分裂成两部分）。\n拓扑预测（Topology Prediction）： 预测物体的 拓扑结构（genus, 组件数），比如：是否分裂？是否合并？是否变成一个环？ 采用Cross-Attention计算物体在不同时间步的拓扑关系。\n最终输出：完整物体的形状（Occupancy Map, Point Cloud, Mesh）和拓扑结构。\n","date":"2025-03-06T10:51:30+08:00","image":"https://Peraspera1.github.io/images/doughs/cover.png","permalink":"https://Peraspera1.github.io/p/dough/","title":"Dough"},{"content":"Cosmos+ComfyUI 环境配置记录 配置ComfyUI 环境 官方推荐的是python=3.12版本，但是由于我的cuda是11.7版本，没有对应的pytorch，所以我改成了3.11版本的python及其对应的pytorch，这里的版本可根据需要自行修改。\n在终端中输入：\n1 2 3 4 5 6 7 conda create --name comfyui python=3.11 conda activate comfyui conda install pytorch==2.5.1 torchvision==0.15.2 torchaudio==2.0.2 pytorch-cuda=12.1 -c pytorch -c nvidia git clone https://github.com/comfyanonymous/ComfyUI.git cd ComfyUI/ pip install -r requirements.txt -i https://pypi.mirrors.ustc.edu.cn/simple/ 之后运行\n1 python main.py 出现如下结果： 打开网站后结果如下 至此comfyUI配置完成\nCosmos 相关配置 下载 语言模型 并保存到ComfyUI/models/text_encoders/ 路径下\n下载 vae 并保存到 ComfyUI/models/vae/ 路径下\n下载 cosmos模型 并保存到 ComfyUI/models/diffusion_models 路径下\nComfyUI 工作流配置 在官方文档中，下载对应的json文件并保存到comfyui下的workflow的文件夹（自己新建），下图以text2video为例\n然后在网页端打开这个工作流直接运行就可以了\n踩坑 Q1\n1 module \u0026#39;torch\u0026#39; has no attribute \u0026#39;float8_e4m3fn\u0026#39; A1\ntorch版本太低了，升级到pytorch=2.5.1+cuda=12.1就好\nComfyui 基本使用方法 安装了两个插件还挺好用的，分别是AlekPet和VHS\n","date":"2025-03-04T16:22:05+08:00","image":"https://Peraspera1.github.io/images/cosmos/cover.png","permalink":"https://Peraspera1.github.io/p/cosmos/","title":"Cosmos"},{"content":"论文信息 信息概览 RAL 2023\n论文题目： Differentiable Physics Simulation of Dynamics-Augmented Neural Objects\n论文单位： MIT\n是否开源： 否\n总结： 输入未经处理的rgb视频，使用可微分物理引擎来模拟其在施加的力和扭矩下的运动\n论文细节 1 估计物体质量、质心、惯性矩阵和表面摩擦系数，通过表面接触的概率?\n总体思想如下：\n他们主要的创新点还是在提取物体表面上做的，但该方法是建立在nerf场上的，没必要借鉴，在3DGS的情况下应该有更好的表示方式。 总之，这个工作主要还是建立在dojo这个他们MIT自己研究的仿真平台上的，不一定有泛用性，而且这个平台已经停止开发了。 可以去研究下genesis是怎么工作的。\n相关论文 “Marching cubes: A high resolution 3d surface construction algorithm” siggraph 生成物体表面的网格模拟运动\n","date":"2025-03-03T10:04:23+08:00","image":"https://Peraspera1.github.io/images/DANOs/cover.png","permalink":"https://Peraspera1.github.io/p/danos/","title":"DANOs"},{"content":"尽管当前的视频生成模型已能产生令人满意的效果，但生成的结果中仍常出现不自然的现象(Sora)，这些现象往往违背了我们对几何和物理常识的理解，因此近年来，许多研究尝试将物理规律融入视频生成模型来得到更好的结果。与此同时，在机器人领域，大多数研究仍主要聚焦于机器人自身的运动轨迹生成，而对环境及交互物体的感知仍停留在视觉信息的层面，未能充分利用物理规律。因此，这篇文章总结了我对近期工作的一些总结，以及一点点对于这些工作在灵巧手操作上可能应用的思考。\n我的想法大致如下： 整个工作的pipeline如下：\n给定一个任务，利用LLM预测我们需要知道哪些物理属性（比如物体的摩擦系数）； 输入一段视频作为监督信号，从该视频的初始帧开始进行物理仿真，优化物理参数场； 得到较为精确的物理参数后，生成/仿真得到该物体在被施加一个力后的响应； 在已有的手物交互轨迹基础上，如果能准确预测物体对外力的响应，就能进一步微调手的施力方向和大小，或者将这些信息直接融入轨迹生成过程中，以提升交互精度。 一句话概括就是让机器人理解真实环境中的物理属性，从而更好地辅助操作实现。那么自然而然地会引出两个问题，\n首先，如何从环境中恢复物体的物理属性并进行物理仿真？\n其次，在机器人已知物体的物理属性后，如何利用这些信息优化灵巧手的操作？\nPhysics Simulation \u0026amp; Video Generation 事实上，给定视频恢复物理属性(pipeline2)与给定物理属性生成视频(pipeline3)互为反问题(不过我更关注的是生成物体对于外力的响应，并不需要那种精细的视频)。然而，近年来学界的研究更倾向于后者，这一领域的研究主要分为以下三个方向：\n物理对齐 Physics Alignment 在语言模型中，对齐（Alignment）指的是通过一系列算法和工程手段，修正模型的行为，使其输出符合预设的安全边界和人类意图。与之对应的，修正视频模型的输出使其满足物理规则的过程就是物理对齐。作为对齐领域的代表性工作，InstructGPT 提出了两种对齐方法：\n监督微调（Supervised Fine Tuning，SFT）人工标注高质量的提示（prompt）和回答（output）数据集，通过监督学习的方式微调模型。\n基于人类反馈的强化学习（Reinforcement Learning from Human Feedback，RLHF）对同一个提示，模型输出多个回答，人工对这些回答进行比较打分；使用打分的结果训练一个反馈模型（Reward Model），用于评价模型输出的好坏；使用反馈模型对模型进行强化学习，比如近端策略优化（Proximal Policy Gradient，PPO）。\n将这两种想法用于视频模型中是比较直观的。对于 SFT，我们就需要使用物理真实的视频作为输入。但是真实世界中的视频当然都是物理真实的，可能的问题是视频动态不够，导致模型没有接受到足够的动态信息。因此像 Cosmos 在预训练阶段就会保证数据能够反映真实物理规则。这主要是通过两点做到的：\n收集包含大量动态的视频：包括驾驶视频、手部动作、第一人称视角、模拟结果等等。 对数据进行过滤：剔除质量低的、缺乏动态的、非物理等的视频，并提取一部分高质量视频作为后训练数据集。 尽管 Cosmos 的论文在 5.3.2 节专门讨论了物理对齐的问题，但是实际上并没有做更多的尝试，只是在几个场景中测试了 Cosmos 生成的结果是否吻合模拟/真实的物理。\n对于 RLHF 而言，首要问题是需要一个反馈模型来判别模型输出的结果是否满足物理规律。这方向一个代表工作是 VideoPhy。这篇工作的核心是对市面上十二个视频模型的生成结果进行人工打分，然后训练一个打分网络 VideoCon-Physics。打分分为两个维度，每个维度得分只有 0 或 1：一个是语义的符合程度（Semantic Adherence，SA），一个是是否符合物理常识（Physical Commonsense，PC），结果如下： Benchmark 可以发现成绩最好的是开源模型 CogVideoX-5B，但是也只是勉强及格的水平。这方向类似的工作还有 VideoScore，PhyGenBench。理论上有了打分模型之后我们就可以对视频模型进行强化学习对齐了，OnlineVPO 就使用了 VideoScore 作为反馈模型微调了 OpenSora 模型，使其在 VideoScore 得分上超越了其他模型。\n整体上来说，物理对齐比较依赖预训练大模型的能力。对于语言模型来说，对齐往往会降低模型在基准测试上的分数，称为支付对齐税（Alignment Tax）。对于视频模型情况应该是类似的，增强其在物理动态方面的能力可能导致其他能力的削弱。因此，一个更本质的问题是，通过预训练的方式大模型是否能够足够泛化地学到物理规律？字节的工作 How Far is Video Generation from World Model? A Physical Law Perspective 是这个方向的一个初步探索。\n二维平面模拟 2D Physics Ok，如果视频模型短期内无法达到我们对于物理规律的需求，那我们是否可以通过加入物理模拟的方式增强这方面的能力呢？由于视频模型都是 2D 的，我们可以先从二维平面上的模拟开始，这一领域分为两个方向，一个是显式地加入物理规律并在屏幕空间上进行模拟，另一个则是隐式地推断物体的动力学信息。\n屏幕空间模拟（Screen-space Simulation）指的是绕过 3D 模型，直接在屏幕空间中模拟物体的动态。这方面的一个代表性工作是 PhysGen。 Physgen 流程图 大致的流程分为三步：1. 给定一张初始图片，我们先做分割，并使用图像理解模型获取法向贴图、语义等信息，然后使用大语言模型推测对应的材质；2. 使用屏幕空间的 2D 模拟器进行模拟（刚体模拟）；3. 使用视频模型将模拟结果与法向贴图等整合起来，得到最终视频。可以发现，这个流程中其实并不需要大模型生成动态，大模型提供的是一个满足时间连续性的\u0026quot;渲染器\u0026quot;，将模拟结果渲染成视频。最近的 PhysAnimator 也是这个思路，不过将模拟的对象进一步扩展到了布料这样的软性材料。\n当然，也有不显式加入物理模拟的方式来实现图片上的动力学的工作，而是通过分析图片中物体的振动规律得到信息，并利用这些信息来推断物体的物理特性和驱动它们运动的力，这一工作最早可以追溯到Davis的博士论文Visual vibration analysis。如果有了物体对于一个已知力的响应，那么我们是不是就可以在不知道物理规律的前提下分析一个物体对于未知的力的响应了呢（类似于反馈-控制，黑盒模型）？2024年的CVPR Best Paper Generative Image Dynamics 就做了这样的一件事。与PhysGen不同，这篇论文并没有显式地建模出物体的运动规律，而是只学习到了振动频率(事实上，物体振动频率满足该规律：$\\omega = \\sqrt{\\frac{k}{m}}$)，即学习每个像素点的振动规律(利用傅里叶变换分解，学习的参数是傅里叶的系数)。在不考虑训练成本的情况下，相比于显式地模拟，这种方式的推理速度肯定更快，但是显然只能局限于振动这种简单的物理规律，当然，通过改变基函数的方式（比如把傅里叶级数换成勒让德级数）也许可以将该方法推广到更多真实情景，这也是一个值得探索的方向。\n总的来说，在二维平面上的模拟的优点很明显，我们能够对生成的结果进行非常精确的控制，并且在小幅度内基本满足我们对物理规则的认知。但是缺点同样很明显，由于我们是在屏幕空间做分割和模拟，我们永远只能生成物体一面的结果，像布料的遮挡褶皱也无法处理。并且，生成结果的视角只能是固定的。这使得这类方法只适用于生成动态壁纸这样比较受限的应用，不能作为通用的视频生成方法。\n不过我觉得PhysGen的思维范式很好，如果要继续往下做的话我更倾向于在该工作上的框架上去做。\n三维空间模拟 3D Physics 既然 2D 的模拟终究是妥协，那不如我们直接回到三维模拟。回顾传统的图形管线，生成视频的过程大致可以分为准备3D 资产、进行模拟、渲染结果这三步。这三步中预训练的视频模型可以充当一个非常好的渲染器，比如下图展示的，Cosmos 可以将三维模拟的结果风格迁移到真实场景的视频。 Cosmos中的风格迁移 在有 3D 资产和物理参数的基础上，模拟也不是一个困难的问题。传统模拟算法在平衡模拟效果和速度上已经提供了非常多的选择。因此最大的问题在于第一步：对于用户给定的一个语言提示，或者是初始帧，如何获取对应的 3D 资产。对应这两种情况我们可以看到两种解决方法，一是训练文本生成 3D 资产的模型，二是从真实图片中重建。\n首先，世面上已经有很多专注做文本生成 3D 资产的 AI，比如 Rodin，Meshy 等,可以直接将这些模型导入到像 Houdini、Blender 这样的图形软件中进行模拟。之前受到很多关注的 Genesis 想做的就是这个思路。另一方面，过程建模（Procedural Modeling）使用形式语言或者节点化的方式描述模型的生成过程，可以将 3D 模型与文本直接联系起来。比如 SVG 图片使用 html 标记语言，CAD 模型可以完全用代码表示，Houdini 用节点系统描述模型等等。在有了代码化的描述之后，我们就可以通过语言模型去生成这些代码，也就生成了 3D 模型。Infinigen 通过 Blender 构建了描述自然和室内场景的过程建模语言，因此可以实现文本生成三维场景。GPT4Motion 通过 Blender 实现了无训练，直接从文本生成视频的整个流水线。\n如果我们的任务是从初始帧生成视频，就可以考虑从图片重建出 3D 模型。PhysMotion 使用的方法就是从单张图片进行 Gaussian Splatting 的重建，然后接入物质点法进行模拟，最后经过视频模型进行渲染。如果我们的单视角重建（本质上是对其他视角的生成任务）足够好，那么生成视频的质量就有保证。但是话又说回来，我们不正是应该利用预训练视频模型的能力来帮助单视角生成的任务吗？为什么反而抛弃了大模型在这方面的能力而只把大模型作为一个渲染器呢？\n我们可以发现，如果只是用大模型去增强现有的图形管线，那么不可避免的需要很长的管线，并且没有充分利用大模型的能力。最理想的情况是，我们用最少的规则限制和控制信号，提供最基础的三维物理和几何的保证，其他的交给预训练模型补充细节。在这个方向上，CineMaster 是一个很有意思的尝试，只通过最简单的包围盒作为条件，就能实现很好的视频控制生成效果。\n推断物理信息 前文提到的都是在有物理信息的情况下进行仿真/生成的工作(也就是pipeline3)，如果我们希望将这一概念应用于机器人操作，那么关键问题就在于：如何估计现实世界中物体的物理参数？这是一个极具挑战性的问题，因为目前市面上很少有数据集能够提供包括物体质量、弹性系数等在内的各种物理信息。因此，依赖于大规模数据集进行学习来解决这一问题变得非常困难，特别是当数据集质量较低且规模较小时，模型的泛化能力也会受到限制。那么，如何应对这一挑战呢？如果我们选择依赖物理仿真，是否能够提升模型的泛化能力呢？毕竟，像牛顿定律等自然科学规律是普适的。然而，物理仿真对算法的精度要求非常高。基于此，一个较为可行的初步思路是将模型学习与物理仿真结合：首先通过模型学习来获取物体的初始物理属性，如质量、速度等；然后借助传统物理模拟来预测物体未来的运动规律，最后再用神经网络做微调。\n在这个方向，蒋陈凡夫他们组在此基础上做了很多相似的工作，最为出名的是PAC-Nerf 与PhysGaussian。他们的思想非常朴素，但是却很有用。其整体框架如下： 在此基础上，还有两个工作，分别是Physdreamer和DreamGaussian，但是都是一些incremental的工作而且做的都是偏生成方向。Physdreamer应该是这个领域较新的成果了，他们结合了PhysGaussian和DreamGaussian两篇工作，简单点说就是PhysGaussian用了多帧的真实视频作为输入(监督信号)，恢复物理属性后，再去预测渲染未来的视频帧，而Physdreamer则只输入视频的第一帧，由第一帧图片生成后续的帧，并将其作为监督信号，再接入PhysGaussian的框架。缺点是显而易见的，生成的视频质量肯定没办法和真实的视频相比的，而且二者之间的误差肯定会随着时间的推移增加，所以他们只选择了前面生成的10帧左右作为监督，那么也就无法生成长视频序列了。而且他们的结果如下: 这些评分的意思，比如上面表格的第一个内容表示，对于alocosia（这是一种植物）的视频生成，有86%的人认为他们生成的视频在motion realism的指标下比真实的视频还要好，不过都是人工打分的指标，感觉没啥参考性。而且如果想用到操作的领域，用生成去做肯定是不合适的。不过他们的工作中有一个我觉得还不错的点，他们对于所有的Gaussian点做了knn下采样，也就是只对所谓的driven-particle作仿真，这一点大大加快了仿真的速度。又联想到最近的一篇文章A Grid-Free Fluid Solver based on Gaussian Spatial Representation，这篇工作看格式应该是要投SIGGRAPH的，他们是在PhysGaussian的基础上加速了流体的仿真，简单点说就是原本3DGS核携带的信息是球谐函数，他们把这个信息改成了物理属性，或者可以这么理解，本来3DGS渲染的是RGB，他们改成了渲染速度矢量($V_x, V_y, V_z$)。这个思路我感觉挺好的，而且可以和之前knn下采样的思路结合，我们可以在这个基础上继续加新的东西，而且他们的代码还没有开源，所以我最近有时间的话想从头复现下这篇论文，顺便学习下cuda的代码。\n总的来说，我个人感觉这个领域做的人比较少，而且这些工作的不足之处也非常明显，比如首先他们不能将物体的前景与背景分离开来(比如可以参考PhysGen的pipeline,并用LOTUS做分割?)，其次他们还是只能模拟简单的物理规律，比如他们都把花朵建模为了纯粹的弹性-质点模型，而且在物理规律模拟的过程中都是比较传统的算法，这对于机器人的操作来说都是必须要解决的问题，我感觉这个领域还是值得研究的。\n机器人中的应用 Application in Robot 在机器人领域的调研中，最符合我idea的工作是这篇23年的RAL DANOs。\n可以参考他们的视频作进一步的了解。 他们的工作是通过纯粹的视觉信息来估计物体的质量，重心，摩擦系数这些属性并辅助机械爪工作，由于是23年的工作，所以他们的框架还是建立在Nerf的基础上的，也就是先建立一个体素场，然后在体素的密度和质量之间，通过神经网络的方式建立一个映射，从而恢复出物体的属性。而且他们还在实物实验上验证了他们的结果，不过这个实物实验比较简单，就是一个肥皂在桌子上滑动，然后预测摩擦力/重力，算出物体的运动规律。\n那么由这个工作出发，自然地会想到两条路径。首先，目前，3DGS技术已经被广泛应用，并且相比NeRF，其基于点云的表示方式在物理仿真中更具优势。因此，直接将 NeRF替换为3DGS是一个显而易见的改进方向。这个工作一眼就能看出来能和PhysGaussian结合，虽然我没找到相关工作，但肯定有人会去做，不过别人可能是普通的二爪机械手，我们是灵巧手，而且还能加入触觉信息，这也是我觉得一个可以探索的方向。\n其次由这个工作，我还联想到了很多预训练上的工作，例如，在现实任务中，机械手可能难以直接抓取桌面上的一张卡片，而更合理的策略是先将卡片推到桌子的边缘，再进行夹取。本质上，这一推卡片的过程与上述预测摩擦力/重力的方法是相似的，都涉及物理信息的推理与利用。然而，据我观察，大部分机器人领域的研究仍然主要关注于抓取姿态的生成，即如何在几何层面找到最优的抓取方式，而对物体的物理属性（如摩擦、质心、变形）以及环境因素的考量较少。因此，我的研究想法正是希望从物理信息的角度出发，探索更加智能的抓取策略。（如果后续要做这个方向上的工作，我希望能从这个简单的任务（推卡片）开始做）\n有人可能会质疑：如果目标是执行某些运动学任务（如推卡片、打乒乓球等），为什么不直接用端到端控制器进行学习？目前已有研究通过强化学习等方法，成功训练出了能够打乒乓球或羽毛球的机器人，是否还有必要引入物理建模？\n首先，从直觉上来说，我觉得通过物理规律建模得到的结果可以泛化到很多未知的情境中，端到端的控制方法虽然可以在特定任务上表现出色，但它们通常是基于数据驱动的黑盒模型，容易受到环境因素（如颜色、光照变化等）的干扰。而基于物理规律的建模方法则能够泛化到更多未知场景，不依赖于特定数据分布。\n其次，按照我文章一开始提出的overview，哪一个环节出现了问题，对于我来说都是可控的，这种可控性使得物理建模能够更好地与新兴的研究成果结合（比如之前提到的lotus），并进行模块化优化。而端到端学习往往难以解释模型的决策逻辑，并且对于计算资源的消耗量巨大。\n第三，打乒乓球这种工作只能局限于运动学模型，而对于更精细的操作（如灵巧手抓取柔性物体、操纵复杂工具、物体局部形变等），物理仿真能够提供更完整的解释。例如，在精细抓取任务中，局部形变、摩擦力、微观接触点的作用不可忽视，而这些信息很难通过端到端的黑盒方法直接学习到。\nReference Physics for Large Video Model\n","date":"2025-02-27T12:49:57+08:00","image":"https://Peraspera1.github.io/images/summary_cover.png","permalink":"https://Peraspera1.github.io/p/phys_summary/","title":"Physics_Summary"},{"content":"全局修改 在 /assets/scss/custom.scss 中加入以下代码：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 // 页面基本配色 :root { // 全局顶部边距 --main-top-padding: 30px; // 全局卡片圆角 --card-border-radius: 25px; // 标签云卡片圆角 --tag-border-radius: 8px; // 卡片间距 --section-separation: 40px; // 全局字体大小 --article-font-size: 1.8rem; // 行内代码背景色 --code-background-color: #f8f8f8; // 行内代码前景色 --code-text-color: #e96900; // 暗色模式下样式 \u0026amp;[data-scheme=\u0026#34;dark\u0026#34;] { // 行内代码背景色 --code-background-color: #ff6d1b17; // 行内代码前景色 --code-text-color: #e96900; } } //------------------------------------------------------ // 修复引用块内容窄页面显示问题 a { word-break: break-all; } code { word-break: break-all; } //--------------------------------------------------- // 文章内容图片圆角阴影 .article-page .main-article .article-content { img { max-width: 96% !important; height: auto !important; border-radius: 8px; } } //------------------------------------------------ // 文章内容引用块样式 .article-content { blockquote { border-left: 6px solid #358b9a1f !important; background: #3a97431f; } } // --------------------------------------- // 代码块基础样式修改 .highlight { max-width: 102% !important; background-color: var(--pre-background-color); padding: var(--card-padding); position: relative; border-radius: 20px; margin-left: -7px !important; margin-right: -12px; box-shadow: var(--shadow-l1) !important; \u0026amp;:hover { .copyCodeButton { opacity: 1; } } // keep Codeblocks LTR [dir=\u0026#34;rtl\u0026#34;] \u0026amp; { direction: ltr; } pre { margin: initial; padding: 0; margin: 0; width: auto; } } // light模式下的代码块样式调整 [data-scheme=\u0026#34;light\u0026#34;] .article-content .highlight { background-color: #fff9f3; } [data-scheme=\u0026#34;light\u0026#34;] .chroma { color: #ff6f00; background-color: #fff9f3cc; } //------------------------------------------- // 设置选中字体的区域背景颜色 //修改选中颜色 ::selection { color: #fff; background: #34495e; } a { text-decoration: none; color: var(--accent-color); \u0026amp;:hover { color: var(--accent-color-darker); } \u0026amp;.link { color: #4288b9ad; font-weight: 600; padding: 0 2px; text-decoration: none; cursor: pointer; \u0026amp;:hover { text-decoration: underline; } } } //------------------------------------------------- //文章封面高度更改 .article-list article .article-image img { width: 100%; height: 150px; object-fit: cover; @include respond(md) { height: 200px; } @include respond(xl) { height: 305px; } } //--------------------------------------------------- // 全局页面布局间距调整 .main-container { min-height: 100vh; align-items: flex-start; padding: 0 15px; gap: var(--section-separation); padding-top: var(--main-top-padding); @include respond(md) { padding: 0 37px; } } //-------------------------------------------------- //页面三栏宽度调整 .container { margin-left: auto; margin-right: auto; .left-sidebar { order: -3; max-width: var(--left-sidebar-max-width); } .right-sidebar { order: -1; max-width: var(--right-sidebar-max-width); /// Display right sidebar when min-width: lg @include respond(lg) { display: flex; } } \u0026amp;.extended { @include respond(md) { max-width: 1024px; --left-sidebar-max-width: 25%; --right-sidebar-max-width: 22% !important; } @include respond(lg) { max-width: 1280px; --left-sidebar-max-width: 20%; --right-sidebar-max-width: 30%; } @include respond(xl) { max-width: 1453px; //1536px; --left-sidebar-max-width: 15%; --right-sidebar-max-width: 25%; } } \u0026amp;.compact { @include respond(md) { --left-sidebar-max-width: 25%; max-width: 768px; } @include respond(lg) { max-width: 1024px; --left-sidebar-max-width: 20%; } @include respond(xl) { max-width: 1280px; } } } //------------------------------------------------------- //全局页面小图片样式微调 .article-list--compact article .article-image img { width: var(--image-size); height: var(--image-size); object-fit: cover; border-radius: 17%; } 总字数统计 在layouts/partials/footer/footer.html里增加以下代码\n1 2 3 4 5 6 7 8 9 \u0026lt;!-- Add total page and word count time --\u0026gt; \u0026lt;section class=\u0026#34;totalcount\u0026#34;\u0026gt; {{$scratch := newScratch}} {{ range (where .Site.Pages \u0026#34;Kind\u0026#34; \u0026#34;page\u0026#34; )}} {{$scratch.Add \u0026#34;total\u0026#34; .WordCount}} {{ end }} 发表了{{ len (where .Site.RegularPages \u0026#34;Section\u0026#34; \u0026#34;post\u0026#34;) }}篇文章 · 总计{{ div ($scratch.Get \u0026#34;total\u0026#34;) 1000.0 | lang.FormatNumber 2 }}k字 \u0026lt;/section\u0026gt; 在assets/scss/partials/footer.scss里修改风格：\n1 2 3 4 5 .totalcount { color: var(--card-text-color-secondary); font-weight: normal; margin-bottom: 5px; } 不过按照这个方法似乎并不能够正确统计全文的字数，\n单篇文章的字数统计 参考了这篇文章\n代码块装饰 1 准备一张喜欢的风格的图片(svg格式)放到static/icons文件夹下\n2 将以下代码复制进assets/scss/custom.scss文件中(不存在则自行创建)\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 .highlight { border-radius: var(--card-border-radius); max-width: 100% !important; margin: 0 !important; box-shadow: var(--shadow-l1) !important; } .highlight:before { content: \u0026#34;\u0026#34;; display: block; background: url(../icons/macOS-code-header.svg) no-repeat 0; background-size: contain; height: 18px; margin-top: -10px; margin-bottom: 10px; } 代码块展开\u0026amp;收起 (1) 准备一张向下展开图片(Ctrl+S保存)，放到assets/icons目录下\n(2) 将以下代码复制进layouts/partials/footer/custom.html(文件不存在则自行创建)\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \u0026lt;style\u0026gt; .highlight { /* 你可以根据需要调整这个高度 */ max-height: 400px; overflow: hidden; } .code-show { max-height: none !important; } .code-more-box { width: 100%; padding-top: 78px; background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0)), to(#fff)); position: absolute; left: 0; right: 0; bottom: 0; z-index: 1; } .code-more-btn { display: block; margin: auto; width: 44px; height: 22px; background: #f0f0f5; border-top-left-radius: 8px; border-top-right-radius: 8px; padding-top: 6px; cursor: pointer; } .code-more-img { cursor: pointer !important; display: block; margin: auto; width: 22px; height: 16px; } \u0026lt;/style\u0026gt; \u0026lt;script\u0026gt; function initCodeMoreBox() { let codeBlocks = document.querySelectorAll(\u0026#34;.highlight\u0026#34;); if (!codeBlocks) { return; } codeBlocks.forEach(codeBlock =\u0026gt; { // 校验是否overflow if (codeBlock.scrollHeight \u0026lt;= codeBlock.clientHeight) { return; } // 元素初始化 // codeMoreBox let codeMoreBox = document.createElement(\u0026#39;div\u0026#39;); codeMoreBox.classList.add(\u0026#39;code-more-box\u0026#39;); // codeMoreBtn let codeMoreBtn = document.createElement(\u0026#39;span\u0026#39;); codeMoreBtn.classList.add(\u0026#39;code-more-btn\u0026#39;); codeMoreBtn.addEventListener(\u0026#39;click\u0026#39;, () =\u0026gt; { codeBlock.classList.add(\u0026#39;code-show\u0026#39;); codeMoreBox.style.display = \u0026#39;none\u0026#39;; // 触发resize事件，重新计算目录位置 window.dispatchEvent(new Event(\u0026#39;resize\u0026#39;)) }) // img let img = document.createElement(\u0026#39;img\u0026#39;); img.classList.add(\u0026#39;code-more-img\u0026#39;); img.src = \u0026#34;{{ (resources.Get \u0026#34;icons/codeMore.png\u0026#34;).Permalink }}\u0026#34; // 元素添加 codeMoreBtn.appendChild(img); codeMoreBox.appendChild(codeMoreBtn); codeBlock.appendChild(codeMoreBox) }) } initCodeMoreBox(); \u0026lt;/script\u0026gt; 修改字体 (1) 前往100font下载自己想要的字体保存为ttf文件\n(2) 把字体文件放入assets/font下(文件夹自己创建)\n(3) 将以下代码修改并复制到layouts/partials/footer/custom.html文件中(文件不存在就自己创建)\n1 2 3 4 5 6 7 8 9 10 11 \u0026lt;style\u0026gt; @font-face { font-family: \u0026#39;字体名\u0026#39;; src: url({{ (resources.Get \u0026#34;font/字体文件名\u0026#34;).Permalink }}) format(\u0026#39;truetype\u0026#39;); } :root { --base-font-family: \u0026#39;字体名\u0026#39;; --code-font-family: \u0026#39;字体名\u0026#39;; } \u0026lt;/style\u0026gt; ","date":"2025-02-26T12:42:52+08:00","image":"https://Peraspera1.github.io/images/cybercover.jpg","permalink":"https://Peraspera1.github.io/p/%E8%B5%9B%E5%8D%9A%E8%A3%85%E4%BF%AE%E8%AE%B0%E5%BD%95/","title":"赛博装修记录"},{"content":"论文信息 信息概览 ECCV 2024 Oral Presentation\n论文题目： PhysDreamer: Physics-Based Interaction with 3D Objects via Video Generation\n论文单位： MIT\n是否开源： 是\n总结： 一种基于物理学的方法，通过利用视频生成模型学习的对象动力学先验，赋予静态3D对象交互式动力学，也就是使静态3D对象能够以物理上似乎合理的方式动态响应交互刺激。\n该方法使用3D高斯粒子表示物体，使用神经场建模材料属性，并通过可微分仿真（使用材料点法，MPM）模拟动态。\n论文思路 问题：给一张图片，比如一朵花，想知道这朵花在微风吹过后的动态信息，也就是求一个物体对于新物理交互的响应。\n但是求解这个响应，需要对物体的性质有较为准确的估计（比如两种弹性系数不同的弹簧，对其施加相同大小和方向的力，其变形显然是不一样的）。\n而这个性质是很难测量的，或者说难以形成大规模的数据集以供学习。\n但是人类能从观察物理世界和与物理世界互动中获得的物理先验知识，受此启发，作者从大量的视频先验中学习动力学先验，\n为了简化，这篇文章只对弹性物体做了仿真，那么估计的物理属性，有质量、杨氏模量和泊松比。质量等于密度乘体积，论文中粒子的体积是体素的体积除以其中包含的粒子数，密度是给定的常数，泊松比也是给定的常数，所以最后优化的只是一个杨氏模量的场。\n论文的关键思想是生成运动中物体的合理demo，比如一朵花，他把花离散为很多稠密的点，但这些点不是同构的，因此每个点的杨氏模量都不一样，然后按照物理属性去优化材质场E以匹配这个合成的运动。 我们首先从某个视点为 3D 场景出发渲染静态图像。然后，我们利用图像到视频模型(SVD)生成一个短视频剪辑 {$I_0$， $I_1$， . . . ， $I_T$ }，描绘对象的真实运动，这个生成的模型是GT来监督模拟得到的图像，然后再通过可微分模拟和可微渲染来优化材料场E(x)和初始速度场$v_0$(x)，使得模拟的渲染视频与生成的视频匹配。 但其实我觉得核心的部分还是图中下面的箭头，也就是PhysGaussian的工作比较重要。\n细节部分 仿照PhysGaussian内部填充？\n核心的仿真原理： $$ \\rho \\frac{D v}{D t} = \\nabla \\cdot \\sigma + f, \\frac{D \\rho}{D t} + \\rho \\nabla \\cdot v = 0 $$v 是欧拉视角，密度是常量，f是外力。\nMPM的实现细节需要单独花时间细看。\n总体可以概括如下： $$ x^{t+1}, v^{t+1}, F^{t+1}, C^{t+1} = S(x^{t}, v^{t}, F^{t}, C^{t}, \\theta , \\Delta t) $$F和C分别是局部变形场的梯度和应力场的梯度，$\\theta$ 代表所有的物理量，在文章里代表E，$\\Delta \\approx 1 \\times 10^{-4}$，仿真了100步。\n对于每一步，按如下公式渲染： $$ \\hat{I}^t = F_{render}(x^t, \\alpha, R^t, \\Sigma, c) $$R代表所有粒子的旋转矩阵，\n优化的参数是杨氏模量和初始帧的速度，损失函数定义如下： $$ L^t = \\lambda L_1(\\hat{I}^t, I^t) + (1-\\lambda)L_{D-SSIM}(\\hat{I}^t, I^t) $$创新点(MPM加速) 高斯模型包含成千上万个点，这对于模拟来说效率较低。因此，本文采用了下采样方法，每个下采样后的点能够有效描述其对应领域的信息。此外，下采样对3D几何形状（3DGS）的表征同样至关重要。因为3DGS表征存在过于局部化的问题（不同区域之间的表征可能会出现突变或不连贯），这会导致空间表征的不连续性。通过下采样后，每个点包含了其领域的信息，从而有可能推动表征向混合高斯模型（mixture-Gaussian）方向发展，使得空间的整体表示更加连续。这样的方法可能为将三维场景表示为一串序列提供了思路，可以进一步应用于MLLM。例如，可以将该序列视作一个Encoder-Decoder模型，并通过重建信息作为监督信号进行训练。\n结果 数据集：八个真实场景，大部分是花，这个作为对照组\n其实没什么意义，因为本身这篇论文是在前两篇的基础上做的，而且PhysGaussian没有优化物理参数，DreamGaussian没有物理假设。。\n讨论 视频生成的方式 用SVD采样得到了14帧的信息作为监督。\n疑问的点，text-prompt怎么设计，比如花在空中摇摆，或者被人碰了一下，怎么去量化这个幅度？\nloss的设计 用生成得到的视频监督是否合理？ 因为整个3DGS的参数很多，这篇文章只是监督了E，而其他的位置，速度等信息都是仿真算出来的，所以DoF，或者说优化的参数空间其实比较小。但是如果要学习更多的物理信息，只用SVD去监督肯定不合理。\n其次，生成得到的视频离真实场景还是有差别，所以还是要做一个trade-off，一种方法是减少生成视频对模型的影响，例如使用结构损失作为损失函数，或者将生成的视频帧作为guidance来进行distillation，另一种是降低估计的Dof，想这篇文章做的那样，固定泊松比和质量，只估计杨氏模量，第三种方式是提高视频生成的能力，脱离SDS损失函数的监督，转向全监督学习，即让生成的视频与真实场景之间有更多直接的监督。\n","date":"2025-02-25T00:00:00Z","image":"https://Peraspera1.github.io/images/physdreamer_cover.jpg","permalink":"https://Peraspera1.github.io/p/physdreamer/","title":"Physdreamer"},{"content":"论文信息 信息概览 CVPR 2024 Highlight\n论文题目： PhysGaussian: Physics-Integrated 3D Gaussians for Generative Dynamics\n论文单位： UCLA\n是否开源： 是\n总结： PhysGaussian是第一篇将3D高斯核（用于渲染）与物理属性（如速度、应变、应力）相结合，使其能够模拟牛顿力学中的动态行为，适用于多种不同材料（如弹性物体、金属、非牛顿流体等）。\n论文思路 核心思想是what you see is what you simulate。\n传统的图形学物理引擎往往会导致模拟与可视化之间的差别，但自然界中材料的物理特性与视觉外观本质上也是交织在一起的，受此启发，本文将物理学赋予 3D 高斯核，赋予它们运动学属性（如速度和应变）以及机械属性（如弹性能、应力和塑性），进而弥补这一差别。\n首先需要输入一个物体的多视角图片，然后按照传统3DGS的方式重建物体，得到物体的3DGS表示(不要渲染)，即把物体离散为了一个个高斯（高斯的中心、不透明度、协方差矩阵和球谐系数）\n代码debug记录 ","date":"2025-02-19T00:00:00Z","image":"https://Peraspera1.github.io/images/physgaussian_cover.jpg","permalink":"https://Peraspera1.github.io/p/physgaussian/","title":"Phygaussian"},{"content":"论文信息 CVPR 2024 Best Paper\n论文题目： Generative Image Dynamics\n是否开源： 否\n总结：\n一种从静态图像生成动态运动的方法，特别是针对自然的振荡运动，如树木在风中摇动、花朵或蜡烛火焰的摆动等。 核心思想是使用频谱体积，这是一种基于频率的像素运动表示，通过真实视频序列进行学习。\n细节 输入单张图片$I_0$, 输出${\\hat{I}_1, \\hat{I}_2, ..., \\hat{I}_T}$，\n用LDM从输入的单张图片中预测谱体积 $\\mathcal{S}=\\left(S_{f_0},S_{f_1},...,S_{f_{K-1}}\\right)$ ，然后再利用这个谱体积恢复$\\mathcal{F}=(F_1,F_2,...,F_T)$，即后面T个时刻的运动。$F_t(p)$ 代表t时刻$I_0$中第p个像素的位置。（$I_t^\\prime(\\mathbf{p}+F_t(\\mathbf{p}))=I_0(\\mathbf{p})$）\nspectral volume（谱体积）： 从视频中提取的每像素轨迹的时间傅里叶变换。\n频谱分析-\u0026gt;解决生成视频的长期时间一致性??\nk个频率，(x,y)+- 共4K个channel\n对于一张 $H \\times W$的图片，每个像素p可以表示为$I_{t}(p) = \\Sigma_{k} [Asin(k \\omega x t) + B cos(k \\omega x t)]$\n值得阅读的参考论文\nMyers Abraham Davis. Visual vibration analysis. PhD thesis, Massachusetts Institute of Technology, 2016.\n","date":"2025-02-17T00:00:00Z","image":"https://Peraspera1.github.io/post/GID/GIDfront.jpg","permalink":"https://Peraspera1.github.io/p/generativeid/","title":"Generative Image Dynamics"},{"content":"跨实体灵巧抓取的机器人与物体交互的统一表示 ","date":"2024-12-19T00:00:00Z","image":"https://Peraspera1.github.io/p/dro/DROfront.png","permalink":"https://Peraspera1.github.io/p/dro/","title":"D(R,O) Grasp"},{"content":" hello hugo\n","date":"2024-12-18T00:00:00Z","permalink":"https://Peraspera1.github.io/p/huber/","title":"Huber"},{"content":"Mast3r - SLAM 定义 dust3r/mast3r 输入$\\mathcal{I}^i,\\mathcal{I}^j\\in\\mathbb{R}^{H\\times W\\times3}$\n得到$\\mathbf{X}_i^i,\\mathbf{X}_i^j\\in\\mathbb{R}^{H\\times W\\times3}$及对应的置信度 $\\mathrm{C}_i^i,\\mathrm{C}_i^j\\in\\mathbb{R}^{H\\times W\\times1}$\n$\\mathbf{X}_j^i$是图片i的点云在相机j下面的坐标\n相比于dust3r,mast3r还输出了每个像素的特征向量$\\mathrm{D}_i^i,\\mathrm{D}_i^j\\in\\mathbb{R}^{H\\times W\\times d}$，及$\\mathrm{Q}_i^i,\\mathrm{Q}_i^j\\in\\mathbb{R}^{H\\times W\\times1}$。类似于特征子和描述子。\n将mast3r的输出结果合并记为：$\\mathcal{F}_M(\\mathcal{I}^i,\\mathcal{I}^j)$\n一对图片的匹配集合表示为：$\\mathbf{m}_{i,j}=\\mathcal{M}(\\mathbf{X}_i^i,\\mathbf{X}_i^j,\\mathbf{D}_i^i,\\mathbf{D}_i^j)$\n整体思路 1 前端优化：逐帧优化相机位姿，构建局部地图。\n2 后端优化：全局优化所有关键帧和地图点，修正漂移和保证全局一致性。\n前端优化 目标有两个：\n1 在新帧和最近关键帧之间进行相机位姿的局部优化。\n2 在局部范围内融合点地图（点云融合）。\n点图匹配 数学推导如下（从几何角度上理解更为直观）：\n为了进行局部的位姿优化，首先需要找到两张图之间的对应点：\nprojective data-association：\n利用相机投影模型（例如针孔模型或其他中心投影模型，本文用的是射线），将 3D 点投影到图像平面上，并找到对应的像素位置。在投影到的像素周围局部搜索对应的观测点（例如通过颜色、特征等进行匹配）。 通过这种投影与局部搜索，实现高效且准确的点匹配，而不需要全局特征匹配（如耗时的 brute-force 特征匹配）。\n但是这个模型需要准确的相机参数-\u0026gt;构建相机模型\ndef : 对于一幅图像中的点云，光线定义为从相机中心指向某个 3D 点的单位向量。 作者采用的方式：基于迭代优化求解，最小化投影光线之间的角度误差优化的参数是： $\\mathbf{T}= \\begin{bmatrix} s\\mathbf{R} \u0026 \\mathbf{t} \\\\ 0 \u0026 1 \\end{bmatrix}$， 及图片之间的像素的匹配关系\n$$\\mathbf{p}^*=\\arg\\min_\\mathbf{p}\\left\\|\\psi\\left([\\mathbf{X}_i^i]_\\mathbf{p}\\right)-\\psi\\left(\\mathbf{x}\\right)\\right\\|^2.$$$$\\left\\|\\psi_1-\\psi_2\\right\\|^2=2(1-\\cos\\theta),\\quad\\cos\\theta=\\psi_1^T\\psi_2.$$\n只有外参和尺度，没有估计内参，利用cuda并行加速\n过滤点的方式：过滤三维空间中距离相差较大的点(文中没有提到具体的做法)\n点图匹配的优化方法 目标： 找到两张图片之间的对应点\n初始化：恒等映射，即按像素坐标映射\n优化的方程：\n$$\\mathbf{p}^*=\\arg\\min_\\mathbf{p}\\left\\|\\psi\\left([\\mathbf{X}_i^i]_\\mathbf{p}\\right)-\\psi\\left(\\mathbf{x}\\right)\\right\\|^2.$$优化的变量：以第一张图片为参考系，逐像素优化第二张图片的对应点的像素坐标(u,v)，这个过程可以在GPU上并行运算(cuda)，并且文中提到只要10次迭代就可以收敛(速度比mast3r找对应点的方式更快吗?)\n跟踪 估计当前帧(f)和最后一个关键帧(k)的相对位姿变换\n什么叫使用网络的单次传递来估计变换？\n损失函数: mast3r会估计出图片1的在图片2坐标系下的点云、图片2对应的点云在图片2坐标系下的点云（反过来也是一样的），这两个点云只相差了一个坐标变换矩阵（以及尺度？同一个pair下面也会有尺度不一致吗？）。这个损失函数应该只考虑了置信度较高的特征点对应的像素对应的点云。\n$$E_p=\\sum_{m,n\\in\\mathbf{m}_{f,k}}\\left\\|\\frac{\\tilde{\\mathbf{X}}_{k,n}^k-\\mathrm{T}_{kf}\\mathrm{X}_{f,m}^f}{w(\\mathrm{q}_{m,n},\\sigma_p^2)}\\right\\|_\\rho$$$$\\mathrm{q}_{m,n}=\\sqrt{\\mathrm{Q}_{f,m}^f\\mathrm{Q}_{f,n}^k}$$ q是描述子的内积; (这个$\\sigma$没有定义？)\n$$w(\\mathbf{q},\\sigma^2)= \\begin{cases} \\sigma^2/\\mathbf{q} \u0026 \\mathbf{q}\u003e\\mathbf{q}_{min} \\\\ \\infty \u0026 \\mathrm{otherwise} \u0026 \u0026 \\end{cases}.$$如何解决3D点深度不一致的问题-\u0026gt;光线误差（而不是重投影）+点云融合\n利用射线的角度误差而非投影误差（这个误差对深度不敏感）\n$$E_r=\\sum_{m,n\\in\\mathbf{m}_{f,k}}\\left\\|\\frac{\\psi\\left(\\tilde{\\mathbf{X}}_{k,n}^k\\right)-\\psi\\left(\\mathbf{T}_{kf}\\mathbf{X}_{f,m}^f\\right)}{w(\\mathbf{q}_{m,n},\\sigma_r^2)}\\right\\|_\\rho.$$角度误差是有界的，基于射线的误差对异常值具有鲁棒性。因为：1.相比直接使用 3D 点误差，射线误差（角度误差）更鲁棒，因为它只考虑方向，而不依赖于深度的绝对精度。 避免尺度问题：2.由于单目 SLAM 中的尺度不确定性，使用射线误差能够更好地处理尺度问题。\n我们还包括一个关于距离相机中心的距离差的小权重的误差项。这防止了系统在纯旋转情况下退化，但较小的权重避免了像点位误差那样对位姿估计产生偏差。？？？\n点云融合 点云融合的方式，加权平均 $$\\tilde{\\mathbf{X}}_{k}^{k}\\leftarrow\\frac{\\tilde{\\mathbb{C}}_{k}^{k}\\tilde{\\mathbb{X}}_{k}^{k}+\\mathbb{C}_{f}^{k}\\left(\\mathbb{T}_{kf}\\mathbb{X}_{f}^{k}\\right)}{\\tilde{\\mathbb{C}}_{k}^{k}+\\mathbb{C}_{f}^{k}},\\tilde{\\mathbb{C}}_{k}^{k}\\leftarrow\\tilde{\\mathbb{C}}_{k}^{k}+\\mathbb{C}_{f}^{k}.$$置信度直接相加吗？-\u0026gt;某一个点的置信度会越来越高\n后端优化 图的构建以及回环检测 怎么判断一个图片是否是关键帧？\n通过mast3r构建一个pair，同时输入最后一个关键帧和当前的图片，计算匹配的像素点的数量，如果这个数量低于某一个值，那就说明这个新加入的图片能够产生足够多的新的点云，因此就把这张图作为关键帧。\ngraph的顺序是什么？\n按照时间顺序串联，同时维护一个边的集合，每次加入两个关键帧之间的边（双向）\n局部的回环检测和全局的回环检测\n采用MASt3R-SfM使用的聚合选择性匹配内核 (ASMK)框架(?)，用于从编码特征进行图像检索。 这样就能找到两张类似的图片来进行回环检测。（但是文章中没有提到增量式建立ASMK框架的过程以及检测到回环之后调整全局位姿的方法？）\n后端优化 后端优化的方法，对于边的集合中所有的图片一起进行优化\n$$E_g=\\sum_{i,j\\in\\mathcal{E}}\\sum_{m,n\\in\\mathbf{m}_{i,j}}\\left\\|\\frac{\\psi\\left(\\tilde{\\mathbf{X}}_{i,m}^i\\right)-\\psi\\left(\\mathbf{T}_{ij}\\tilde{\\mathbf{X}}_{j,n}^j\\right)}{w(\\mathbf{q}_{m,n},\\sigma_r^2)}\\right\\|_\\rho$$假设集合中有N个关键帧，那么形成了2N个边（双向边，形成了回环），每个关键帧有7个自由度（3 个旋转、3 个平移和 1 个尺度）\n数学公式推导 ","date":"2024-12-17T00:00:00Z","image":"https://Peraspera1.github.io/p/mast3rslam/image.png","permalink":"https://Peraspera1.github.io/p/mast3rslam/","title":"Mast3r-slam"}]