Skip to content

Fix flaky spline interpolation test - #556

Open
URJala wants to merge 7 commits into
UniversalRobots:masterfrom
URJala:fix_flaky_spline_interpolation_test
Open

Fix flaky spline interpolation test#556
URJala wants to merge 7 commits into
UniversalRobots:masterfrom
URJala:fix_flaky_spline_interpolation_test

Conversation

@URJala

@URJala URJala commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Made new method: sendTrajectoryAndConfirmStart which launches an async thread to confirm that a new trajectory resets the spline_travel_time and then starts executing. This is more robust than the previous implementation.

I have replaced all the calls to sendTrajectory where they were immediately followed by waitForTrajectoryStarted, with one call to sendTrajectoryAndConfirmStart. waitForTrajectoryStarted is no longer used, but I havent removed it yet.


Note

Low Risk
Changes are confined to spline interpolation test code and timing/synchronization logic; no robot driver or production paths are modified.

Overview
Spline interpolation integration tests were flaky because trajectory upload and “has it started?” checks ran sequentially on the main thread, so spline travel time in RTDE could be read too late or miss the reset when overlapping trajectories.

sendTrajectoryAndConfirmStart starts confirmTrajectoryStarted on a background thread (std::async), waits until that thread is polling RTDE, then sends the spline on the main thread. The helper thread watches output_double_register_1: it expects travel time to drop or hit zero when a new plan is accepted, then waits until travel time moves past ~2 ms to mean execution started, issuing trajectory NOOPs while sending. Shared state uses a mutex, condition variable, and atomics (async_ready, async_stop, trajectory_sent).

Tests that previously called sendTrajectory plus waitForTrajectoryStarted now ASSERT_TRUE(sendTrajectoryAndConfirmStart(...)), including cases that send a second trajectory without canceling or after cancel. waitForTrajectoryStarted remains in the file but is unused.

Reviewed by Cursor Bugbot for commit d4cd181. Bugbot is set up for automated code reviews on this repo. Configure here.

Made new method: sendTrajectoryAndConfirmStart which launches an async thread to confirm that a new trajectory resets the spline_travel_time and then starts executing. This is more robust than the previous implementation.

I have replaced all the calls to sendTrajectory where they were immediately followed by waitForTrajectoryStarted, with one call to sendTrajectoryAndConfirmStart.
waitForTrajectoryStarted is no longer used, but I havent removed it yet.
Copilot AI balanced review requested due to automatic review settings August 19, 2026 13:55
@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.42%. Comparing base (2379c42) to head (4e94127).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #556      +/-   ##
==========================================
- Coverage   79.48%   79.42%   -0.06%     
==========================================
  Files         116      116              
  Lines        6969     6969              
  Branches     3083     3083              
==========================================
- Hits         5539     5535       -4     
- Misses       1049     1051       +2     
- Partials      381      383       +2     
Flag Coverage Δ
check_version_ur10-3.15.8 11.50% <ø> (-1.43%) ⬇️
check_version_ur10e-10.11.0 11.50% <ø> (ø)
check_version_ur10e-5.15.2 11.84% <ø> (+0.28%) ⬆️
check_version_ur12e-10.12.1 11.50% <ø> (ø)
check_version_ur12e-5.25.1 11.50% <ø> (-0.10%) ⬇️
check_version_ur15-10.12.1 11.50% <ø> (-0.05%) ⬇️
check_version_ur15-5.25.1 11.50% <ø> (-0.20%) ⬇️
check_version_ur16e-10.12.1 11.50% <ø> (ø)
check_version_ur16e-5.25.1 11.75% <ø> (+0.04%) ⬆️
check_version_ur18-10.12.1 11.50% <ø> (ø)
check_version_ur18-5.25.1 11.50% <ø> (ø)
check_version_ur20-10.12.1 11.50% <ø> (-0.05%) ⬇️
check_version_ur20-5.25.1 11.50% <ø> (-0.05%) ⬇️
check_version_ur3-3.14.3 12.93% <ø> (-0.05%) ⬇️
check_version_ur30-10.12.1 11.50% <ø> (ø)
check_version_ur30-5.25.1 12.26% <ø> (+0.75%) ⬆️
check_version_ur3e-10.11.0 11.55% <ø> (+0.04%) ⬆️
check_version_ur3e-5.9.4 11.75% <ø> (-0.52%) ⬇️
check_version_ur5-3.15.8 12.93% <ø> (+0.09%) ⬆️
check_version_ur5e-10.11.0 11.50% <ø> (-0.05%) ⬇️
check_version_ur5e-5.12.8 11.55% <ø> (+0.04%) ⬆️
check_version_ur7e-10.11.0 11.50% <ø> (ø)
check_version_ur7e-5.22.2 11.50% <ø> (ø)
check_version_ur8long-10.12.1 11.50% <ø> (-0.05%) ⬇️
check_version_ur8long-5.25.1 11.50% <ø> (ø)
python_scripts 75.90% <ø> (ø)
start_ursim 84.28% <ø> (+0.66%) ⬆️
ur20-latest ?
ur5-3.14.3 75.36% <ø> (-0.07%) ⬇️
ur5e-10.11.0 70.01% <ø> (-0.11%) ⬇️
ur5e-10.12.0 71.14% <ø> (-0.07%) ⬇️
ur5e-10.7.0 69.40% <ø> (-0.16%) ⬇️
ur5e-5.9.4 75.80% <ø> (+0.12%) ⬆️
ur7e-10.13.0 71.17% <ø> (-0.07%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

Copilot AI 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.

Pull request overview

Improves spline interpolation integration-test reliability by monitoring trajectory startup concurrently with upload.

Changes:

  • Adds asynchronous trajectory-start confirmation.
  • Replaces separate send/wait calls with the combined helper.
  • Adds synchronization state for the watcher.
Suppressed comments (1)

tests/test_spline_interpolation.cpp:332

  • Correct the spelling of “Continously” to “Continuously”.
      // Continously check spline travel time

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/test_spline_interpolation.cpp
Comment thread tests/test_spline_interpolation.cpp
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 19, 2026 14:04

Copilot AI 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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

tests/test_spline_interpolation.cpp:333

  • Correct the spelling of “Continously” in this new comment.
      // Continously check spline travel time

Comment thread tests/test_spline_interpolation.cpp Outdated
Comment on lines +213 to +214
// Wait for trajectory to start (should be quick)
if (confirm_future.wait_for(std::chrono::milliseconds(500)) != std::future_status::ready)
Copilot AI review requested due to automatic review settings August 20, 2026 07:11

Copilot AI 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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (2)

tests/test_spline_interpolation.cpp:217

  • This 500 ms deadline preempts the helper's own 1-second start/reset timeouts, so a valid start that takes 500–1000 ms is forcibly stopped and reported as a failure. That shortens the previous test tolerance and can preserve the flakiness this change is intended to remove; make the outer deadline longer than the internal timeout.
    if (confirm_future.wait_for(std::chrono::milliseconds(500)) != std::future_status::ready)

tests/test_spline_interpolation.cpp:336

  • Correct the spelling of “Continously” to “Continuously.”
      // Continously check spline travel time

Copilot AI review requested due to automatic review settings August 20, 2026 07:26

Copilot AI 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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (2)

tests/test_spline_interpolation.cpp:336

  • Correct the spelling of “Continuously.”
      // Continously check spline travel time

tests/test_spline_interpolation.cpp:342

  • This reset can be observed before sendTrajectory() has sent the new TRAJECTORY_START. Moreover, splineTimerTraveled resets for every spline segment (resources/external_control.urscript:402-404), so an existing trajectory crossing a segment boundary can set this flag and later satisfy the > 0.002 check even if the new trajectory was not accepted. Use a separate signal set immediately after sending the new START command, and only treat resets observed after that signal as confirmation; trajectory_sent is too late because it is set after all points are uploaded.
      if (spline_travel_time < start_spline_travel_time || spline_travel_time == 0.0)
      {
        spline_travel_time_reset = true;
      }

URJala added 2 commits August 20, 2026 08:24
Also add debug messages when failing
Also make reverse socket read blocking
Copilot AI review requested due to automatic review settings August 20, 2026 09:02

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit e1aa95b. Configure here.

Comment thread tests/test_spline_interpolation.cpp Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (1)

tests/test_spline_interpolation.cpp:350

  • When the register is initially 0.0, spline_travel_time_reset becomes true before the upload starts, so this worker may send a NOOP concurrently with sendTrajectory() sending its NOOP/START messages. The reverse socket write path does not serialize concurrent writes, which can reorder or interleave control frames and reintroduce flakiness. Gate this keepalive on the existing trajectory_sent flag (or otherwise serialize all reverse-interface writes).
        if (!g_my_robot->getUrDriver()->writeTrajectoryControlMessage(
                urcl::control::TrajectoryControlMessage::TRAJECTORY_NOOP))

Copilot AI review requested due to automatic review settings August 20, 2026 09:34

Copilot AI 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.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (1)

tests/test_spline_interpolation.cpp:327

  • When the pre-send travel time is already 0.0 (notably on the first test after startup), the worker only considers the reset observed if it receives another zero-valued RTDE package after notifying the sender. If the sender starts the spline before that next package, the first value can already be positive, so the loop never sets this flag and falsely times out. Treat the zero baseline already sampled immediately before signaling readiness as the reset state, then wait for the timer to advance.
    bool spline_travel_time_reset = false;

@URJala
URJala requested a review from urfeex August 20, 2026 10:19
}

// Confirm that the new trajectory is running
if (std::abs(spline_travel_time) > start_spline_travel_time)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Wouldn't this be problematic when there was a long trajectory running beforehand? I don't remember by hard when we reset the spline_travel_time, but it seems fragile to rely on it being small in the beginning. Once it has been reset, being larger than a reasonable threshold should be sufficient, right?

waitForTrajectoryStarted();
ASSERT_TRUE(sendTrajectoryAndConfirmStart(s_pos, s_vel, std::vector<urcl::vector6d_t>(), s_time));

g_trajectory_running = true;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could probably set this inside sendTrajectoryAndConfirmStart, right?

async_cv.notify_one();
}

bool spline_travel_time_reset = false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
bool spline_travel_time_reset = false;
bool spline_travel_time_reset = start_spline_travel_time == 0.0;

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.

3 participants