Skip to content

If no new commands are received, halt#440

Open
urfeex wants to merge 7 commits intoUniversalRobots:masterfrom
urfeex:halt_on_communication_loss
Open

If no new commands are received, halt#440
urfeex wants to merge 7 commits intoUniversalRobots:masterfrom
urfeex:halt_on_communication_loss

Conversation

@urfeex
Copy link
Member

@urfeex urfeex commented Feb 17, 2026

Currently, we only exit the main loop when no new command is received anymore (already taking any configured receive timeout into account).

However, if we don't receive a new command anymore, that should always be considered an unintentional interruption of the control flow. In that case, we should stop program execution, as interrupting the communication was an unexpected error event.

If interrupting the communication in order to continue with the rest of the program was intentional, users will send a stop command. This will end the main control loop at another code branch leading to a clean shutdown of the external_control part in order to be able to continue with the rest of the program.

This should be closing #438 but in order to make sense with the ROS drivers, we would need UniversalRobots/Universal_Robots_ROS2_Driver#1678 and potentially UniversalRobots/Universal_Robots_ROS_Driver#767 before merging this.


Note

Medium Risk
Changes the ExternalControl URScript timeout path to actively stop motion and halt, which can change behavior for users relying on timeout-as-exit. Also tweaks TCP server disconnect callback behavior, which may affect shutdown/cleanup edge cases but is narrowly scoped and covered by updated/new tests.

Overview
ExternalControl now treats missing commands as a hard fault. When the reverse_socket read times out, the URScript no longer just exits the loop; it issues stopj(STOPJ_ACCELERATION) and halt to stop the robot program immediately.

Test infrastructure was refactored and expanded. A new TestableTcpServer helper centralizes connection/message/disconnect waiting and simplifies existing TCP/stream/producer/pipeline/socket tests, and new integration tests (test_external_control_program.cpp, wired into tests/CMakeLists.txt) assert the new timeout-halting behavior while ensuring an explicit stopControl() path still allows the program to continue.

TCP server shutdown behavior is slightly tightened. TCPServer::handleDisconnect() now only fires disconnect_callback_ while keep_running_ is true, avoiding callbacks during teardown.

Written by Cursor Bugbot for commit a10563a. This will update automatically on new commits. Configure here.

@urfeex urfeex requested a review from a team February 17, 2026 15:00
@codecov
Copy link

codecov bot commented Feb 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.30%. Comparing base (59db585) to head (de9ef02).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #440      +/-   ##
==========================================
+ Coverage   76.28%   76.30%   +0.01%     
==========================================
  Files         105      105              
  Lines        5537     5537              
  Branches      593      593              
==========================================
+ Hits         4224     4225       +1     
+ Misses       1015     1013       -2     
- Partials      298      299       +1     
Flag Coverage Δ
start_ursim 83.21% <ø> (-1.16%) ⬇️
ur20-latest 68.71% <ø> (-0.02%) ⬇️
ur5-3.14.3 71.95% <ø> (+0.19%) ⬆️
ur5e-10.11.0 64.90% <ø> (-0.16%) ⬇️
ur5e-10.12.0 66.22% <ø> (+0.08%) ⬆️
ur5e-10.7.0 64.23% <ø> (+0.12%) ⬆️
ur5e-5.9.4 72.48% <ø> (ø)

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

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

Copy link
Member

@urrsk urrsk left a comment

Choose a reason for hiding this comment

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

We should add a test covering this.

@urfeex
Copy link
Member Author

urfeex commented Feb 18, 2026

We should add a test covering this.

Sounds good, I also have an idea for that in mind. It's a bit more complicated, as we need to generate a PolyScope program and require the EC URCap to run that, but it should be possible to do. I just don't know when I will have the time to spend on this.

@urfeex urfeex force-pushed the halt_on_communication_loss branch 2 times, most recently from 8c48d9c to a10563a Compare March 3, 2026 14:14
Copy link

@cursor cursor bot left a comment

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 and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

std::ofstream out_file;
out_file.open(modified_script_path);
out_file << prog;
out_file.close();
Copy link

Choose a reason for hiding this comment

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

Silent write failure in extendScript temp file

Low Severity

extendScript opens ofs on the temp file for error-checking but never writes through it, then opens a second std::ofstream (out_file) to the same file while ofs is still open. On Windows, two simultaneous write handles to the same file cause a sharing violation, so out_file.open() silently fails. There is no check of out_file's error state after open() or operator<<, so the function returns the path to an empty file and the test proceeds with an unusable script. Additionally, the file descriptor returned by mkstemp is discarded via std::ignore, causing a resource leak.

Fix in Cursor Fix in Web

urfeex added 6 commits March 3, 2026 15:55
Currently, we only exit the main loop when no new command is received
anymore (already taking any configured receive timeout into account).

However, if we don't receive a new command anymore, that should always
be considerd an unintentional interruption of the control flow. In that
case, we should stop program execution, as interrupting the
communication was an unexpected error event.

If interrupting the communication in order to continue with the rest of
the program was intentional, users will send a stop command. This will
end the main control loop at another code branch leading to a clean
shutdown of the external_control part in order to be able to continue
with the rest of the program.
@urfeex urfeex force-pushed the halt_on_communication_loss branch from a10563a to 7dd910f Compare March 3, 2026 16:11
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.

2 participants