Newton 扩展属性(Extended Attributes)完全指南:State 与 Contacts 按需分配的力与加速度数组

Newton 扩展属性(Extended Attributes)完全指南:State 与 Contacts 按需分配的力与加速度数组 Newton 扩展属性Extended Attributes完全指南State 与 Contacts 按需分配的力与加速度数组【免费下载链接】newtonAn open-source, GPU-accelerated physics simulation engine built upon NVIDIA Warp, specifically targeting roboticists and simulation researchers.项目地址: https://gitcode.com/GitHub_Trending/newton9/newton本文系统讲解 Newton基于 NVIDIA Warp 的 GPU 加速物理仿真引擎中State与Contacts对象的**扩展属性Extended Attributes**机制如何通过Model/ModelBuilder在创建对象之前按名请求可选数组、各求解器如何填充这些数组、以及精度语义上的注意事项。读完本文你将能够在自己的仿真管线中按需启用接触力、刚体加速度、父级关节反作用力与 MuJoCo 执行器力并为SensorContact、SensorIMU等传感器正确配置数据通道。背景为什么要按需分配Newton 的State状态与Contacts接触对象承载仿真中随时间变化的核心数据。其中大部分数组如body_q、body_qd、rigid_contact_normal等是每次创建对象时必定分配的因为求解器与渲染管线始终需要它们。但还有一类数组不是每次都需要——例如只有接触传感器才关心的接触力、只有 IMU 才需要的刚体加速度。如果无条件分配这些数组任何仿真哪怕只跑一个简单的自由落体都要为它们付出额外的显存与初始化开销。因此 Newton 将这类数据设计为扩展属性extended attributes默认不分配只有在被显式请求时才分配从而在不需要它们的仿真中显著降低内存占用。核心机制见 newton/_src/sim/state.py 与 newton/_src/sim/contacts.py 中EXTENDED_ATTRIBUTES的注释Names of optional extended state/contact attributes that are not allocated by default.默认不分配的扩展属性名集合。扩展接触属性请求与使用请求 API 与最小示例扩展接触属性是挂在Contacts上的可选数组例如供传感器使用的接触力。请求方式有两种任选其一Model.request_contact_attributes(force)在模型已finalize()之后ModelBuilder.request_contact_attributes(force)在构建阶段、finalize()之前。但都必须在创建Contacts对象之前调用。文档给出的最小示例import newton builder newton.ModelBuilder() body builder.add_body(mass1.0) builder.add_shape_sphere(body, radius0.1) model builder.finalize() # 直接请求 force 扩展接触属性 model.request_contact_attributes(force) pipeline newton.CollisionPipeline(model) contacts pipeline.contacts() print(contacts.force is not None) # True在构建阶段请求同样有效且更常见于需要一次配置、多处复用的管线builder newton.ModelBuilder() body builder.add_body(mass1.0) builder.add_shape_sphere(body, radius0.1) builder.request_contact_attributes(force) # 在 finalize 之前 model builder.finalize()ModelBuilder.request_contact_attributes与Model.request_contact_attributes的实现完全对称见 newton/_src/sim/builder.py 与 newton/_src/sim/model.py它们都先调用Contacts.validate_extended_attributes(attributes)校验名称再把名称并入内部的_requested_contact_attributes集合finalize()时该集合会被拷贝到 Model 上newton/_src/sim/builder.py随后由CollisionPipeline.contacts()或直接构造Contacts时通过requested_attributes参数生效。唯一的内置接触扩展属性force规范列表由Contacts.EXTENDED_ATTRIBUTES给出newton/_src/sim/contacts.py当前仅包含一项属性说明force接触空间力spatial force被newton.sensors.SensorContact使用从源码结构看force的数据布局与语义在 contacts.py 中有精确定义类型wp.spatial_vector前三个分量是线性力[N]后三个是力矩[N·m]长度rigid_contact_max soft_contact_max即刚体接触与软体接触共享同一数组软体接触的力排在刚体接触之后参考点与坐标系力与力矩是 body0 受到 body1 施加的作用参考 body0 的质心COM在世界系中表达其中 body0/body1 分别是 shape0/shape1 所属刚体分配条件仅在requested_attributes中包含force时分配if requested_attributes and force in requested_attributes:并且支持requires_grad即可微分离散化仿真场景中梯度可穿透接触力。传感器透明请求无需手动调用部分组件会在初始化时透明地transparently请求它们所需的扩展属性。例如SensorContact在构造时会自动调用model.request_contact_attributes(force)newton/_src/sensors/sensor_contact.pyrequest_contact_attributesTrue为默认值。因此只要在创建 Contacts 之前创建传感器就可以省去手动请求import warp as wp import newton from newton.sensors import SensorContact builder newton.ModelBuilder() builder.add_ground_plane() body builder.add_body(xformwp.transform((0, 0, 0.1), wp.quat_identity())) builder.add_shape_sphere(body, radius0.1, labelball) model builder.finalize() sensor SensorContact(model, sensing_shapesball) # 透明请求 force pipeline newton.CollisionPipeline(model) contacts pipeline.contacts() print(contacts.force is not None) # True在SensorContact的update()中若contacts.force is None会直接抛出ValueErrorsensor_contact.py并要求在sensor.update()之前先调用solver.update_contacts(contacts)以保证接触力为最新值。若你直接构造Contacts而非通过CollisionPipeline则需要手动传入requested_attributes{force}。扩展状态属性请求与使用请求 API 与最小示例扩展状态属性是挂在State上的可选数组例如供传感器使用的加速度。同样有两种请求方式Model.request_state_attributes(...)在finalize()之后ModelBuilder.request_state_attributes(...)在构建阶段。必须在调用Model.state()之前请求。文档示例import newton builder newton.ModelBuilder() body builder.add_body(mass1.0) builder.request_state_attributes(body_qdd) model builder.finalize() state model.state() print(state.body_qdd is not None) # TrueModel.state()的实现会先读取模型上累积的请求集合再据此分配扩展数组newton/_src/sim/model.py。内置扩展状态属性清单规范列表由State.EXTENDED_ATTRIBUTES给出其分配元数据定义在State.EXTENDED_ATTRIBUTE_TEMPLATESnewton/_src/sim/state.py属性分配频率数据类型说明body_qddBODY每刚体一个wp.spatial_vector刚体质心在世界系中的空间加速度[m/s², rad/s²]前三个分量为质心线性加速度后三个为角加速度。被newton.sensors.SensorIMU使用body_parent_fBODY每刚体一个wp.spatial_vector刚体父级交互力parent interaction wrenches即来自关节传入的力/力矩[N, N·m]世界系、以刚体质心为参考点mujoco.qfrc_actuatorJOINT_DOF每关节自由度一个wp.float32广义关节 DOF坐标下的执行器力命名空间为state.mujoco.qfrc_actuator仅由newton.solvers.SolverMuJoCo填充注意第三项的命名空间语义名称中的冒号:会被拆分为命名空间:属性名最终挂到State的mujoco命名空间对象上分配逻辑见 model.py。因此在请求时直接写model.request_state_attributes(mujoco:qfrc_actuator)访问时则是state.mujoco.qfrc_actuator而非state.qfrc_actuator。从 newton/_src/solvers/mujoco/kernels.py 可以看出该数组由 MuJoCo 的mjw_qfrc_actuator维度[nworld, nv]转换而来自由关节free joint的 6 个分量按平动 世界系转动展开其余关节按顺序写入扁平 DOF 数组。传感器透明请求一览「先创建传感器、后分配 State/Contacts」的约定可以推广到所有传感器SensorIMU构造时默认request_state_attributesTrue调用model.request_state_attributes(body_qdd)newton/_src/sensors/sensor_imu.py若state.body_qdd is Noneupdate()会抛出ValueError提示Create SensorIMU before Statesensor_imu.py。SensorContact构造时默认request_contact_attributesTrue请求force见上文。这一设计让用户无需记忆每个传感器依赖哪个扩展属性只要保证传感器对象创建在Model.state()/CollisionPipeline.contacts()之前数据通道就会自动就绪。各求解器的填充行为与精度语义扩展属性只是分配出来的数组具体数值由求解器在step()时填充。不同求解器的支持矩阵文档 Notes 节 源码交叉验证如下求解器body_qddbody_parent_fmujoco:qfrc_actuatorforceSolverMuJoCo填充填充填充填充SolverFeatherstone—填充RNEA 后向传递——SolverXPBD—填充近似—填充近似SolverKamino填充步平均———SolverFeatherstoneRNEA 后向传递直接输出body_parent_f由 Featherstone 求解器从递归牛顿-欧拉算法RNEA的后向传递直接获得。专用 kernelcompute_body_parent_fnewton/_src/solvers/featherstone/kernels.py将父关节反作用力以世界系、质心参考的形式写入数组其注释明确说明坐标系约定与SolverMuJoCo以及State.body_parent_f的定义保持一致。调用点在 newton/_src/solvers/featherstone/solver_featherstone.py仅当state_out.body_parent_f is not None时才启动该 kernel再次体现了按需填充、避免无用计算的设计。SolverXPBD近似值勿当作精确解析量SolverXPBD会填充body_parent_f与force但其文档明确警告newton/_src/solvers/xpbd/solver_xpbd.pyXPBD 报告的 wrench 是近似的它对每个约束修正应用松弛因子relaxation factors且不保证动量守恒因此应理解为施加的约束反作用applied constraint reaction而非精确的解析值具体松弛参数包括joint_linear_relaxation0.7、joint_angular_relaxation0.4、rigid_contact_relaxation0.8、soft_body_relaxation0.9、soft_contact_relaxation0.9等默认值收敛性保证对于简单解耦情形例如单个动态刚体悬挂在运动学kinematic或世界父体上XPBD 值会收敛到积分器一阶时间步进偏差first-order time-stepping bias范围内。SolverKamino离散步平均加速度SolverKamino在请求时把body_qdd填充为离散步平均加速度(body_qd_out - body_qd_in) / dtnewton/_src/solvers/kamino/_src/core/bodies.py。文档特别指出newton/_src/solvers/kamino/solver_kamino.py跨越一次碰撞/冲击时该值会包含速度冲量除以dt的贡献因此它衡量的是步内的平均加速度与连续时间意义上的瞬时加速度不同——在设计控制器或滤波器时需留意这一点。名称校验与错误处理两个validate_extended_attributes类方法提供了统一的名称校验state.py 与 contacts.py传入空集合时直接返回一旦出现不在EXTENDED_ATTRIBUTES中的名称抛出ValueError错误信息会同时列出非法名称与所有允许的名称例如Unknown extended state attribute(s): body_xyz. Allowed: body_parent_f, body_qdd, mujoco:qfrc_actuator.这一机制能及早捕获拼写错误避免在仿真中途才发现数组缺失。与State.assign/ CUDA Graph 的交互扩展属性在状态交换场景下同样被完整支持。State.assign(other)用于把另一个 State 的数组内容复制进当前 State典型用途CUDA Graph 捕获中奇数步长时的状态交换。其实现state.py会复制顶层wp.array属性自动发现所有Model.AttributeNamespace命名空间容器并递归复制——这一机制统一覆盖了扩展属性如mujoco.qfrc_actuator与自定义命名空间属性通过ModelBuilder.add_custom_attribute注册若一侧有数组而另一侧缺失抛出ValueError指明缺失的限定名如mujoco.qfrc_actuator。这意味着一个 State 请求了扩展属性、另一个没请求时assign会立刻报错而不是静默丢数据。实战建议与仓库索引用哪个 API 请求如果在finalize()前后都有清晰的代码分段两种方式等价推荐把请求写在finalize()之前Builder 阶段与场景定义放在一起便于他人阅读。参考 newton/tests/kamino/test_kamino_sensor_imu.py 中的builder.request_state_attributes(body_qdd)模式。接触力的典型消费场景传送带/接触力分析类测试大量使用model.request_contact_attributes(force)见 newton/tests/test_conveyor_forces.py、newton/tests/test_solver_xpbd.py、newton/tests/test_mujoco_solver.py 与 newton/tests/kamino/test_kamino_geometry_contacts.py。可运行的完整示例见 newton/examples/basic/example_basic_conveyor_forces.py 及newton/examples/kamino/下多个示例。务必遵守时序传感器先创建、State/Contacts 后分配solver.update_contacts(contacts)先于sensor.update()。违反时序时Newton 会以明确的ValueError提示你。理解求解器语义再消费数据XPBD 的力是带松弛的近似反作用力Kamino 的加速度是步平均量MuJoCo 的执行器力在mujoco命名空间下——根据你的目标求解器选择合适的数组并在文档/注释中记录精度前提。【免费下载链接】newtonAn open-source, GPU-accelerated physics simulation engine built upon NVIDIA Warp, specifically targeting roboticists and simulation researchers.项目地址: https://gitcode.com/GitHub_Trending/newton9/newton创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考