Skip to content

feat(simulation): add deterministic device reset - #20

Merged
Mile-Away merged 1 commit into
mainfrom
codex/simulation-device-reset
Sep 26, 2026
Merged

Mile-Away merged 1 commit into
mainfrom
codex/simulation-device-reset

Conversation

@Mile-Away

@Mile-Away Mile-Away commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

What changed

Simulation transports now retain configured initial properties and expose a deterministic reset action. The backend reset hook is overridable so future physics engines can reset native world state together with OpenSDL telemetry.

Every configured simulation device advertises the action when it is not already present.

Validation

  • cargo fmt --all
  • cargo test -p osdl-core --features espnow (123 unit, 6 e2e MQTT, 18 integration)

Sourcery 总结

为模拟传输添加确定性的设备重置支持。

新功能:

  • 为已配置的模拟设备添加确定性重置操作,以恢复其初始属性和模拟进度。

增强功能:

  • 允许模拟后端覆盖重置行为,以协调原生世界状态的重置。

测试:

  • 添加测试覆盖,验证重置会恢复已配置的遥测属性、重置步数计数器并记录重置操作。
Original summary in English

Summary by Sourcery

Add deterministic device reset support to simulation transports.

New Features:

  • Add a deterministic reset action to configured simulation devices, restoring their initial properties and simulation progress.

Enhancements:

  • Allow simulation backends to override reset behavior for coordinated native world-state resets.

Tests:

  • Add coverage verifying that reset restores configured telemetry properties, resets the step counter, and records the reset action.

@sourcery-ai

sourcery-ai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

审查者指南

模拟设备现在会保留其配置的初始属性,并提供确定性的重置操作。重置行为通过可重写的后端钩子实现,以便未来的物理引擎集成可以在重置 OpenSDL 遥测数据的同时重置原生状态;同时,测试覆盖了属性和步数的恢复。

确定性模拟设备重置的时序图

sequenceDiagram
    participant Client
    participant OsdlEngine
    participant SimulationTransport
    participant KinematicBackend
    participant Telemetry

    OsdlEngine->>OsdlEngine: register_device
    Client->>SimulationTransport: send(action=reset)
    SimulationTransport->>KinematicBackend: apply_action(state, reset, params)
    KinematicBackend->>KinematicBackend: reset(state)
    KinematicBackend->>SimulationTransport: restore initial_properties and step=0
    SimulationTransport->>Telemetry: publish reset state
    Telemetry-->>Client: properties restored, last_action=reset
Loading

文件级变更

变更 详细信息 文件
在注册期间自动为模拟设备公开一个无模式重置操作。
  • 克隆已配置的操作,并仅在不存在重置操作时追加 reset。
  • 将 reset 描述为将虚拟设备恢复到其配置的初始状态。
crates/osdl-core/src/engine.rs
通过保留初始属性并通过可重写的后端钩子处理重置,使模拟重置具有确定性。
  • 在模拟状态中存储不可变的初始属性快照。
  • 提供默认的后端重置逻辑,用于恢复属性、清除步数计数器并记录重置操作。
  • 在运动学后端操作分发器中处理重置。
  • 从已配置的设备属性初始化快照。
crates/osdl-core/src/transport/simulation.rs
增加测试,覆盖变更后配置值和重置元数据的恢复。
  • 修改模拟温度,执行 reset,并验证初始温度、步数为零以及 last_action 为 reset。
crates/osdl-core/src/transport/simulation.rs

提示和命令

与 Sourcery 交互

  • 触发新的审查: 在拉取请求中评论 @sourcery-ai review。
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 根据审查评论生成 GitHub issue: 回复审查评论,请 Sourcery 根据该评论创建 issue。你也可以回复审查评论并使用 @sourcery-ai issue,根据该评论创建 issue。
  • 生成拉取请求标题: 在拉取请求标题的任意位置写入 @sourcery-ai,即可随时生成标题。你也可以在拉取请求中评论 @sourcery-ai title,以随时生成或重新生成标题。
  • 生成拉取请求摘要: 在拉取请求正文的任意位置写入 @sourcery-ai summary,即可在你指定的位置随时生成 PR 摘要。你也可以在拉取请求中评论 @sourcery-ai summary,以随时生成或重新生成摘要。
  • 生成审查者指南: 在拉取请求中评论 @sourcery-ai guide,即可随时生成或重新生成审查者指南。
  • 解决所有 Sourcery 评论: 在拉取请求中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理完所有评论并且不想再看到它们,此功能会很有用。
  • 忽略所有 Sourcery 审查: 在拉取请求中评论 @sourcery-ai dismiss,即可忽略所有现有的 Sourcery 审查。如果你想从新的审查开始,这尤其有用——别忘了评论 @sourcery-ai review 以触发新的审查!

自定义使用体验

访问你的控制面板以:

  • 启用或禁用审查功能,例如 Sourcery 生成的拉取请求摘要、审查者指南等。
  • 更改审查语言。
  • 添加、删除或编辑自定义审查说明。
  • 调整其他审查设置。

获取帮助

Original review guide in English

Reviewer's Guide

Simulation devices now retain their configured initial properties and expose a deterministic reset action. Reset behavior is implemented through an overridable backend hook so future physics integrations can reset native state alongside OpenSDL telemetry, with tests covering property and step restoration.

Sequence diagram for deterministic simulation device reset

sequenceDiagram
    participant Client
    participant OsdlEngine
    participant SimulationTransport
    participant KinematicBackend
    participant Telemetry

    OsdlEngine->>OsdlEngine: register_device
    Client->>SimulationTransport: send(action=reset)
    SimulationTransport->>KinematicBackend: apply_action(state, reset, params)
    KinematicBackend->>KinematicBackend: reset(state)
    KinematicBackend->>SimulationTransport: restore initial_properties and step=0
    SimulationTransport->>Telemetry: publish reset state
    Telemetry-->>Client: properties restored, last_action=reset
Loading

File-Level Changes

Change Details Files
Automatically expose a schema-less reset action for simulation devices during registration.
  • Clone configured actions and append reset only when absent.
  • Describe reset as restoring the virtual device to its configured initial state.
crates/osdl-core/src/engine.rs
Make simulation reset deterministic by retaining initial properties and routing reset through an overridable backend hook.
  • Store an immutable initial-property snapshot in simulation state.
  • Provide a default backend reset that restores properties, clears the step counter, and records the reset action.
  • Handle reset in the kinematic backend action dispatcher.
  • Initialize the snapshot from configured device properties.
crates/osdl-core/src/transport/simulation.rs
Add coverage for restoring configured values and reset metadata after mutation.
  • Change a simulated temperature, issue reset, and verify initial temperatures, step zero, and last_action reset.
crates/osdl-core/src/transport/simulation.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@Mile-Away
Mile-Away merged commit 66d4179 into main Sep 26, 2026
2 checks passed

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

您好——我发现了 1 个问题

面向 AI Agent 的提示
请处理本次代码审查中的评论:

## 个别评论

### 评论 1
<location path="crates/osdl-core/src/transport/simulation.rs" line_range="63-66" />
<code_context>
+
+    /// Restore the device's configured state. Physics integrations can
+    /// override this to reset their world state alongside the OpenSDL view.
+    async fn reset(&self, state: &mut SimulationState) {
+        state.properties = state.initial_properties.clone();
+        state.step = 0;
+        state.last_action = Some("reset".into());
+    }
 }
</code_context>
<issue_to_address>
**问题 (bug_risk):** 重置状态的修改与重置遥测的发送不是原子的:`reset` 释放状态互斥锁后,ticker 可能会在 `emit_status` 执行前推进状态并加入遥测消息,因此重置响应报告的可能是非零步数或演化后的属性,而不是重置快照。新测试同样会消费下一条遥测消息,因此可能读到这次介入的 tick,并间歇性失败。

**触发条件:** 模拟 ticker 在动作应用与状态发送之间触发时。

**建议修复:** 在单一的命令/遥测同步机制下,确保重置及其对应的状态发送按顺序执行;同时让测试等待 `last_action == "reset"` 的遥测消息,而不是消费任意一条排队中的消息。
</issue_to_address>

Sourcery 对开源项目免费——如果您喜欢我们的审查,请考虑分享 ✨
Original comment in English

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="crates/osdl-core/src/transport/simulation.rs" line_range="63-66" />
<code_context>
+
+    /// Restore the device's configured state. Physics integrations can
+    /// override this to reset their world state alongside the OpenSDL view.
+    async fn reset(&self, state: &mut SimulationState) {
+        state.properties = state.initial_properties.clone();
+        state.step = 0;
+        state.last_action = Some("reset".into());
+    }
 }
</code_context>
<issue_to_address>
**issue (bug_risk):** Reset state mutation and reset telemetry emission are not atomic: after `reset` releases the state mutex, the ticker can advance the state and enqueue telemetry before `emit_status` runs, so the reset response reports a nonzero step or evolved properties instead of the reset snapshot. The new test also consumes whichever telemetry message is next, so it can read that intervening tick and fail intermittently.

**Triggers:** When the simulation ticker fires between action application and status emission.

**Suggested fix:** Keep reset and its corresponding status emission ordered under a single command/telemetry synchronization mechanism, and make the test wait for telemetry with `last_action == "reset"` rather than consuming an arbitrary queued message.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment on lines +63 to +66
async fn reset(&self, state: &mut SimulationState) {
state.properties = state.initial_properties.clone();
state.step = 0;
state.last_action = Some("reset".into());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

问题 (bug_risk): 重置状态的修改与重置遥测的发送不是原子的:reset 释放状态互斥锁后,ticker 可能会在 emit_status 执行前推进状态并加入遥测消息,因此重置响应报告的可能是非零步数或演化后的属性,而不是重置快照。新测试同样会消费下一条遥测消息,因此可能读到这次介入的 tick,并间歇性失败。

触发条件: 模拟 ticker 在动作应用与状态发送之间触发时。

建议修复: 在单一的命令/遥测同步机制下,确保重置及其对应的状态发送按顺序执行;同时让测试等待 last_action == "reset" 的遥测消息,而不是消费任意一条排队中的消息。

Original comment in English

issue (bug_risk): Reset state mutation and reset telemetry emission are not atomic: after reset releases the state mutex, the ticker can advance the state and enqueue telemetry before emit_status runs, so the reset response reports a nonzero step or evolved properties instead of the reset snapshot. The new test also consumes whichever telemetry message is next, so it can read that intervening tick and fail intermittently.

Triggers: When the simulation ticker fires between action application and status emission.

Suggested fix: Keep reset and its corresponding status emission ordered under a single command/telemetry synchronization mechanism, and make the test wait for telemetry with last_action == "reset" rather than consuming an arbitrary queued message.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant