Skip to content

fix(manipulation): stabilize planning group E2E test - #3483

Merged
leshy merged 1 commit into
mainfrom
cc/fix/manip-ci
Aug 16, 2026
Merged

fix(manipulation): stabilize planning group E2E test#3483
leshy merged 1 commit into
mainfrom
cc/fix/manip-ci

Conversation

@TomCC7

@TomCC7 TomCC7 commented Aug 16, 2026

Copy link
Copy Markdown
Member

Summary

  • wait for the OpenArm blueprint's exact planning-group IDs instead of an incorrect group count
  • select left and right planning groups by ID rather than response order
  • report the last observed groups when readiness times out

The single-arm scenario plans for one selected arm, but it runs the dual-arm blueprint. Waiting for one exposed group caused the referenced CI job to time out after the module correctly returned both groups.

Failing job: https://github.com/dimensionalOS/dimos/actions/runs/31864877735/job/94964227657?pr=3422

Test plan

  • pytest dimos/e2e_tests/test_manipulation_planning_groups.py -m self_hosted_large -vv (2 passed)
  • ruff check dimos/e2e_tests/test_manipulation_planning_groups.py
  • ruff format --check dimos/e2e_tests/test_manipulation_planning_groups.py
  • git diff --check

@codecov

codecov Bot commented Aug 16, 2026

Copy link
Copy Markdown

❌ 3 Tests Failed:

Tests completed Failed Passed Skipped
4260 3 4257 69
View the top 2 failed test(s) by shortest run time
dimos.e2e_tests.test_dimsim_path_replaning::test_path_replanning
Stack Traces | 118s run time
lcm_spy = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x71370477dbb0>
start_blueprint = <function start_blueprint.<locals>.set_name_and_start at 0x7137041a6c00>
dim_sim = <dimos.e2e_tests.dim_sim_client.DimSimClient object at 0x7137e9fbce90>
direct_cmd_vel_explorer = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x713704caba10>
spawn_wall_on_pose = <function spawn_wall_on_pose.<locals>.spawn at 0x7137041a7600>

    @pytest.mark.self_hosted_large
    def test_path_replanning(
        lcm_spy, start_blueprint, dim_sim, direct_cmd_vel_explorer, spawn_wall_on_pose
    ) -> None:
        start_blueprint(
            "--dimsim-scene=empty",
            "run",
            "unitree-go2-agentic",
            simulator="dimsim",
        )
        lcm_spy.save_topic(".../McpClient/on_system_modules/res")
        lcm_spy.wait_for_saved_topic(".../McpClient/on_system_modules/res", timeout=1200.0)
    
        # robot spawns at (3, 2)
    
        # side wall
        dim_sim.add_wall(2, -2.5, 12, -2.5)
        # other side wall
        dim_sim.add_wall(2, 3.5, 12, 3.5)
        # back wall (behind robot)
        dim_sim.add_wall(2, -2.5, 2, 3.5)
        # forward wall (far end)
        dim_sim.add_wall(12, -2.5, 12, 3.5)
        # dividing wall at x=7 with doors at y=[-1.5,-0.5] and y=[1.5,2.5]
        dim_sim.add_wall(7, -2.5, 7, -1.5)
        dim_sim.add_wall(7, -0.5, 7, 1.5)
        dim_sim.add_wall(7, 2.5, 7, 3.5)
    
        direct_cmd_vel_explorer.linear_speed = 0.8
>       direct_cmd_vel_explorer.follow_points([(10, 2), (2.5, 2), (3, 2)])

dim_sim    = <dimos.e2e_tests.dim_sim_client.DimSimClient object at 0x7137e9fbce90>
direct_cmd_vel_explorer = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x713704caba10>
lcm_spy    = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x71370477dbb0>
spawn_wall_on_pose = <function spawn_wall_on_pose.<locals>.spawn at 0x7137041a7600>
start_blueprint = <function start_blueprint.<locals>.set_name_and_start at 0x7137041a6c00>

dimos/e2e_tests/test_dimsim_path_replaning.py:47: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../simulation/mujoco/direct_cmd_vel_explorer.py:105: in follow_points
    self._wait_for_pose()
        self       = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x713704caba10>
        waypoints  = [(10, 2), (2.5, 2), (3, 2)]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x713704caba10>

    def _wait_for_pose(self) -> PoseStamped:
        self._new_pose.clear()
        self._new_pose.wait(timeout=5.0)
>       assert self._pose is not None, "No odom received"
E       AssertionError: No odom received

self       = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x713704caba10>

.../simulation/mujoco/direct_cmd_vel_explorer.py:65: AssertionError
dimos.e2e_tests.test_dimsim_walk_forward::test_walk_forward
Stack Traces | 200s run time
lcm_spy = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x7137047943e0>
start_blueprint = <function start_blueprint.<locals>.set_name_and_start at 0x7137041e0400>
human_input = <function human_input.<locals>.send_human_input at 0x7137041e04a0>
dim_sim = <dimos.e2e_tests.dim_sim_client.DimSimClient object at 0x713808a8c080>

    @pytest.mark.self_hosted_large
    def test_walk_forward(lcm_spy, start_blueprint, human_input, dim_sim) -> None:
        start_blueprint(
            "run",
            "--disable",
            "spatial-memory",
            "--disable",
            "security-module",
            "unitree-go2-agentic",
            simulator="dimsim",
        )
        lcm_spy.save_topic(".../McpClient/on_system_modules/res")
        lcm_spy.wait_for_saved_topic(".../McpClient/on_system_modules/res", timeout=1200.0)
    
        origin_x, origin_y = 1, 2
        dim_sim.set_agent_position(origin_x, origin_y)
    
        human_input("move forward 3 meter")
    
>       lcm_spy.wait_until_odom_position(origin_x + 3, origin_y, threshold=0.4, timeout=120)

dim_sim    = <dimos.e2e_tests.dim_sim_client.DimSimClient object at 0x713808a8c080>
human_input = <function human_input.<locals>.send_human_input at 0x7137041e04a0>
lcm_spy    = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x7137047943e0>
origin_x   = 1
origin_y   = 2
start_blueprint = <function start_blueprint.<locals>.set_name_and_start at 0x7137041e0400>

dimos/e2e_tests/test_dimsim_walk_forward.py:37: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/e2e_tests/lcm_spy.py:167: in wait_until_odom_position
    self.wait_for_message_result(
        predicate  = <function LcmSpy.wait_until_odom_position.<locals>.predicate at 0x7137041e0d60>
        self       = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x7137047943e0>
        threshold  = 0.4
        timeout    = 120
        x          = 4
        y          = 2
dimos/e2e_tests/lcm_spy.py:153: in wait_for_message_result
    wait_until(
        event      = <threading.Event at 0x71375e373260: unset>
        fail_message = 'Failed to get to position x=4, y=2'
        listener   = <function LcmSpy.wait_for_message_result.<locals>.listener at 0x7137041e1120>
        predicate  = <function LcmSpy.wait_until_odom_position.<locals>.predicate at 0x7137041e0d60>
        self       = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x7137047943e0>
        timeout    = 120
        topic      = '/odom#geometry_msgs.PoseStamped'
        type       = <class 'dimos.msgs.geometry_msgs.PoseStamped.PoseStamped'>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

predicate = <bound method Event.is_set of <threading.Event at 0x71375e373260: unset>>

    def wait_until(
        predicate: Callable[[], bool],
        *,
        timeout: float,
        interval: float = 0.1,
        message: str | None = None,
    ) -> None:
        """Poll ``predicate`` until it returns truthy or ``timeout`` elapses."""
        deadline = time.monotonic() + timeout
        while time.monotonic() < deadline:
            if predicate():
                return
            time.sleep(interval)
>       raise TimeoutError(message or f"Timed out after {timeout}s waiting for condition")
E       TimeoutError: Failed to get to position x=4, y=2

deadline   = 3334475.6323261
interval   = 0.1
message    = 'Failed to get to position x=4, y=2'
predicate  = <bound method Event.is_set of <threading.Event at 0x71375e373260: unset>>
timeout    = 120

.../utils/testing/waiting.py:35: TimeoutError
View the full list of 1 ❄️ flaky test(s)
dimos.e2e_tests.test_dimsim_spatial_memory::test_go_to_the_bed

Flake rate in main: 16.67% (Passed 125 times, Failed 25 times)

Stack Traces | 107s run time
lcm_spy = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x713808b560c0>
start_blueprint = <function start_blueprint.<locals>.set_name_and_start at 0x7137041a7f60>
human_input = <function human_input.<locals>.send_human_input at 0x7137041e0180>
dim_sim = <dimos.e2e_tests.dim_sim_client.DimSimClient object at 0x7137062ed280>
explore_house = <function explore_house.<locals>.explore at 0x7137041e0860>

    @pytest.mark.self_hosted_large
    def test_go_to_the_bed(lcm_spy, start_blueprint, human_input, dim_sim, explore_house) -> None:
        start_blueprint(
            "run",
            "unitree-go2-agentic",
            simulator="dimsim",
        )
        lcm_spy.save_topic(".../McpClient/on_system_modules/res")
        lcm_spy.wait_for_saved_topic(".../McpClient/on_system_modules/res", timeout=1200.0)
    
>       explore_house()

dim_sim    = <dimos.e2e_tests.dim_sim_client.DimSimClient object at 0x7137062ed280>
explore_house = <function explore_house.<locals>.explore at 0x7137041e0860>
human_input = <function human_input.<locals>.send_human_input at 0x7137041e0180>
lcm_spy    = <dimos.e2e_tests.lcm_spy.LcmSpy object at 0x713808b560c0>
start_blueprint = <function start_blueprint.<locals>.set_name_and_start at 0x7137041a7f60>

dimos/e2e_tests/test_dimsim_spatial_memory.py:28: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
dimos/e2e_tests/conftest.py:249: in explore
    direct_cmd_vel_explorer.follow_points(points)
        direct_cmd_vel_explorer = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x713705cf4830>
        points     = [(3.881, 4.803), (4.16, 1.615), (1.596, 1.505), (1.649, 0.137), (-3.644, -0.064), (-3.759, -2.661), ...]
.../simulation/mujoco/direct_cmd_vel_explorer.py:105: in follow_points
    self._wait_for_pose()
        self       = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x713705cf4830>
        waypoints  = [(3.881, 4.803), (4.16, 1.615), (1.596, 1.505), (1.649, 0.137), (-3.644, -0.064), (-3.759, -2.661), ...]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x713705cf4830>

    def _wait_for_pose(self) -> PoseStamped:
        self._new_pose.clear()
        self._new_pose.wait(timeout=5.0)
>       assert self._pose is not None, "No odom received"
E       AssertionError: No odom received

self       = <dimos.simulation.mujoco.direct_cmd_vel_explorer.DirectCmdVelExplorer object at 0x713705cf4830>

.../simulation/mujoco/direct_cmd_vel_explorer.py:65: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Aug 16, 2026
@leshy
leshy added this pull request to the merge queue Aug 16, 2026
Merged via the queue into main with commit 904b345 Aug 16, 2026
69 of 74 checks passed
@leshy
leshy deleted the cc/fix/manip-ci branch August 16, 2026 08:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Required CI checks have passed on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants