feat!: cut the controller over to phoxal and SimulatorSession - #7
Merged
Conversation
The controller depended on four framework library packages and drove the
transport itself: it opened a `BusOwner` from a `BusConfig::for_external`,
probed the routers for its execution, minted a `TimelineAuthority` and a
`WorldClockPublisher`, and declared each component driver's presence with
`declare_participant_ready_as`.
None of that is a simulator's job, and after the 0.66 topology none of it is
reachable either: raw bus ownership is `pub(crate)` in the one `phoxal` crate.
So the dependency is now one library at its external-simulator profile:
phoxal = { version = "0.66", default-features = false, features = ["simulator"] }
and the plumbing is `phoxal::simulator::SimulatorSession`.
`connect` learns the execution and opens the session; `sample_publisher`,
`state_publisher` and `setpoint_receiver` build the typed component handles on
the endpoint's owner side; `participant_ready_events` observes the Ready
evidence the motor's fixed-source lease stands on; `present` declares one
delegated lease per component instance that declares a `driver` block; and
`close` drops that presence before it lets go of the transport.
`WorldTime` is taken once and moves onto the step-loop thread, exactly as the
authority and the clock publisher did: the world advances, `completed_step`
mints the one token for that advance, every capability publishes with it, and
`publish_clock` closes the step.
A rewind replaces the timeline, every stop still parks the world, and argv is
unchanged.
Payloads are endpoints now, so `SimulatedSensor` names one associated type
instead of a body and a descriptor, and the vendored copy of
`phoxal::SampleSchedule` goes: it was carried across only because depending on
`phoxal` used to mean depending on the participant runner, which
`default-features = false` settles.
The step-loop test is not carried over. It needs a `WorldTime`, which only a
connected `SimulatorSession` hands out, and the `simulator` profile publishes no
session that opens without a live router; the framework proves the world-step
ordering in-crate. The `StepWorld` seam stays for the test to return to.
`SimulatorSession::in_process` is published now, so the loop's own proof comes back: a scripted world publishes one encoder sample per step on a handle taken from a real session, and the loop drives it with the `WorldTime` that session hands out - the same two values `controller::run` wires together. Four ways the loop can stop, one test, because a process may mint exactly one world time and each scenario closes its session before the next one opens: a quit world, a device that refuses a step's outputs, a host signal, and a failing advance. Every one of them leaves the world parked, the two failures reach the caller, and a step's outputs carry the exact instant of the advance that produced them. The enqueue order - a step's outputs on the outbound lane before the clock that closes it - is not asserted here, and the test says so. Reading it needs both sequence numbers from the client side, and the `simulator` profile hands an adapter owner-side handles only; the framework proves it in `world_session_tests.rs` with a real subscriber on each key. Swapping the two publishes in `step_once` leaves every assertion here passing, which is exactly why claiming it would have been worse than not claiming it. The three that do hold were each checked by mutation.
…ose evidence The step thread's join result no longer short-circuits the close: a panicked loop still drops the delegated presence and the transport, and the session's close evidence is reported beside the loop's outcome.
Contributor
Author
|
Review correction applied (2a94302): the session is closed on every exit path of the step thread, a panic included, and its close evidence is reported beside the loop's outcome (adopts the framework's |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The Webots controller depends on the framework as one library with the simulator profile:
phoxal-bus,phoxal-protocol,phoxal-model,phoxal-bundleare gone (framework PR refactor(framework)!: onephoxallibrary with consumer profiles, a Rust-declared api tree, andphoxal::sessionframework#466).BusOwner,BusConfig::for_external,probe_routers,TimelineAuthority,WorldClockPublisher, delegated Ready declaration) is replaced byphoxal::simulator::SimulatorSessionandWorldTime(taken once, owned by the step-loop thread, exactly as before).phoxal::api::topics().component(..)?.<capability>(..)?.<leaf>().owner();FixedSourceLeasestays the adapter's local admission policy.--bundle-root,--connect,--version) unchanged; still a Webots-launched, non-participant process.sample_schedule.rscopy (which existed only because this crate avoidedphoxal) is replaced byphoxal::SampleSchedule.SimulatorSession::in_process); the enqueue-order proof lives framework-side (world_session_tests), which is where the profile keeps client-side observation.Evidence (against the local 0.66 worktree overlay)
cargo fmt --check,cargo check/clippy --all-targets -D warnings,cargo test(35): green.Live Webots run launched by the 0.65-line CLI (
phoxal 0.40.0) withPHOXAL_FRAMEWORK_PATHat the 0.66 framework worktree andPHOXAL_SIMULATOR_WEBOTS_PATHat this branch, on a throwawayrobot-rover: Webots launched the controller with unchanged argv;webots controller ready … capabilities={accelerometer 2, camera 3, depth 1, encoder 4, gnss 1, gyroscope 2, imu 2, motor 4, range 1} presented=8;phoxal statuslifecycle: ready, 20/20 processes present with the 8 driver instances present by delegated presence; world clock advancing on one timeline (step=1 … step=2453, 12 ms basicTimeStep, no spurious rewind); motor lease refusedSourceAbsenton the park path;phoxal stopand a real Ctrl+C in the TUI both exit 0 with zero leftover processes.Landing
Draft until
phoxal 0.66.0is published: the manifest pins the unpublished train andCargo.lockmust be regenerated against it before landing (the CLI installs this package--locked).