fix(sim): apply Replacement teleport fully to the physics body - #6
Open
taitaitai58 wants to merge 1 commit into
Open
fix(sim): apply Replacement teleport fully to the physics body#6taitaitai58 wants to merge 1 commit into
taitaitai58 wants to merge 1 commit into
Conversation
Replacement (robot/ball teleport) already called DynamicRigidBody.reset()
on position, but two gaps left it looking like the physics body never
really moved:
- mocSim_BallReplacement.vx/vy were parsed but silently dropped, so a
teleported ball with a requested launch velocity just sat still.
- A robot's previously-commanded velocity (veltangent/velnormal/velangular)
stayed latched in the Robot model after a teleport, so the very next
tick re-applied it and the robot immediately drove off again — plus the
QML-side pose bookkeeping (prePoses/preVelocities) still held the
pre-teleport pose, reading the position jump itself as a brief phantom
velocity through MotionControl's accel limiter.
Fixes:
- Robot::resetMotion() zeroes kick/spinner/tangent/normal/angular targets
and clears the actuation-delay buffers; observer.cpp calls it for the
replaced robot before re-emitting {blue,yellow}RobotsChanged so QML
picks up the stop immediately instead of waiting on the next commands
packet.
- onRobotReplacementRequested seeds prePoses/preVelocities to the
just-placed, at-rest pose so there's no phantom one-tick velocity.
- observer.cpp now forwards ball vx/vy (m/s -> scene mm/s, same axis
convention as position) through a widened ballReplacementRequested
signal; GameObjects.qml's new placeBall() helper (factored out of the
existing mouse "place ball" path, which behaves identically to before)
applies it via setLinearVelocity() when present.
Verified headless (QT_QPA_PLATFORM=offscreen) by sending mocSim_Packet
Replacement datagrams via protoc --encode and reading back vision:
- Robot teleported mid-command (veltangent latched) now lands and stays
within ~0.05mm over 1.3s, vs. previously coasting away at full speed.
- Ball Replacement with vx/vy now visibly travels and decelerates under
the existing slip/roll friction model instead of sitting still.
- Ball Replacement without vx/vy (the common case) is unaffected: still
placed at rest.
- A second robot's independent, ongoing velocity command is unaffected
by another robot's Replacement (no cross-talk).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Summary
Replacement(robot/ball teleport, from PR #3) already calledDynamicRigidBody.reset()on position, which does genuinely warp the PhysX body — but two gaps made teleport unreliable enough that per-robot placement/calibration on this sim was effectively unusable:mocSim_BallReplacement.vx/vywere parsed but never forwarded to physics — a ball teleported with a requested launch velocity just sat still.veltangent/velnormal/velangularstayed latched in theRobotmodel after a teleport. The very next simulation tick re-applied that stale command, so the robot immediately drove off again — from the outside this looks exactly like "the teleport doesn't move the physics body," even though the position was actually applied for one instant. On top of that, the QML-side pose bookkeeping (prePoses/preVelocities) still held the pre-teleport pose, so the position jump itself read as a brief phantom velocity throughMotionControl's accel limiter, causing a short coast even after the stale-command issue is fixed.Changes
src/models/robot.{h,cpp}: newRobot::resetMotion()— zeroes kick/spinner/tangent/normal/angular targets and clears the actuation-delay pipeline (dead-time buffers) immediately, no ramp-down.src/observer.{h,cpp}:visionReceive()callsresetMotion()on the replaced robot before re-emitting{blue,yellow}RobotsChanged, so QML picks up the stop on the very next tick instead of waiting for the next commands packet. Also decodesballReplacement.vx()/vy()(m/s,has_vx()/has_vy()optional) and forwards them through a widenedballReplacementRequested(sceneX, sceneZ, hasVelocity, sceneVx, sceneVz)signal, converted to scene mm/s with the same axis convention as position (sceneVz = -vy*1000).src/qml/sim/GameObjects.qml:onRobotReplacementRequestednow also seedsprePoses[id]/preVelocities[id]to the just-placed, at-rest pose, eliminating the phantom one-tick velocity.placeBall(scenePosition, velocity)helper, factored out of the existing mouse "place ball" (resetPosition("ball", ...)) code path — that path is behaviorally unchanged (callsplaceBall(pos, null)), it just no longer duplicates the reset logic.onBallReplacementRequesteduses the same helper and passes the velocity through when the packet had one.Test plan
Built and ran headless (
QT_QPA_PLATFORM=offscreen QSG_RENDER_LOOP=basic QT_QUICK_CONTROLS_STYLE=Basic ./bin/m2-Sim), sendingmocSim_PacketReplacementdatagrams viaprotoc --encode=mocSim_Packetto127.0.0.1:20694and reading the SSL vision output back withprotoc --decode=SSL_WrapperPacket.veltangentcommand to robot 2, then teleported it to(-2000, -2000)mid-stream.(-2000, -2000)and drifts < 0.06 mm over 1.3 s (80 vision frames) — i.e. it actually stays put.vx/vy: placed the ball at(1.0, 0.5)m withvx=2.0m/s. Ball now visibly travels (+x) and decelerates under the existing slip/roll friction model, instead of sitting motionless as before.vx/vy(the common case, e.g. kickoff placement): unaffected — ball is placed and stays at rest (drift < 3 mm over 1.25 s, plain numerical/contact jitter).cmake --build .) is clean, no new warnings from the touched files.Not covered: grSim-side / real bridge client verification (tested via a hand-rolled UDP sender against the raw proto, not through a specific AI client's bridge implementation), and the pre-existing mouse-driven "grab & carry" / "place ball" UI paths (unchanged code, not exercised interactively since this was a headless run —
resetPosition("ball", ...)'s behavior was preserved byte-for-byte in theplaceBall()refactor).🤖 Generated with Claude Code