Universal_Robots_Client_Library icon indicating copy to clipboard operation
Universal_Robots_Client_Library copied to clipboard

Modular and Extensible URScript Generation

Open dkar-sto opened this issue 7 months ago • 8 comments

Feature summary

This feature request proposes a fundamental architectural enhancement to the Universal_Robots_Client_Library: the introduction of a modular URScript generation engine. The goal is to allow developers to safely and easily extend the robot's functionality by adding custom URScript commands without needing to fork or directly modify the core library.

Currently, external_control.urscript is a monolithic file, making any customization a complex and brittle process that complicates future library updates. By moving to a dynamic generation model, we can empower users to integrate custom hardware (grippers, sensors, etc.) and application-specific logic in a clean, maintainable, and robust manner.

Detailed Proposal: Self-Contained Command Primitives

The core of this proposal is to define a new C++ interface, let's call it ScriptCommand, which will serve as the base for all extensible commands. Each implementation of the ScriptCommand interface will be a self-contained module that provides all the necessary components for its execution:

  1. C++ Serialization: A method to serialize the command's parameters into a data packet that can be sent to the robot. This encapsulates the communication logic within the command itself.
  2. URScript Snippets: Methods that return the specific URScript code required for the command's operation. This would include:
    • get_urscript_definitions(): Returns any helper functions or global variables the command needs.
    • get_urscript_handler(): Returns the elif block for the main command-handling loop, which decodes the parameters and executes the command logic.
    • get_urscript_teardown(): (Optional) Returns code to be run when the program stops.

This concept could also be extended to Modal Motion Commands (like servoj, speedj) by creating a MotionCommand interface, evolving from the current MotionPrimitive. This interface would provide URScript snippets for a thread template (initCode, execCode, stoppingCode), ensuring that all motion commands adhere to the required safety patterns (e.g., being abortable by a control_mode change).

The Script Generation Engine

A new ScriptGenerator class would be introduced. Before program execution, it would:

  1. Start with a stable, hardcoded base template for external_control.urscript. This template would contain the core socket setup, the main control loops, and the hardcoded logic for complex, motion-integrated features like tool_contact.
  2. Iterate through all ScriptCommand and MotionCommand modules registered with the UrDriver.
  3. Intelligently assemble the final URScript by injecting the snippets from each module into designated placeholders in the base template.

This approach isolates the core, safety-critical logic from user extensions, providing the best of both worlds: robustness and extensibility.

Related issues

none

Tasks

To complete this issue involves

  • [ ] Design and implement the ScriptCommand and MotionCommand C++ interfaces.
  • [ ] Refactor existing commands (set_payload, force_mode, servoj, etc.) to use the new modular interfaces.
  • [ ] Implement the ScriptGenerator class to assemble the final URScript.
  • [ ] Integrate the generator into the UrDriver's startup sequence.
  • [ ] Create comprehensive documentation for the new modular architecture and a guide on how to create and register custom command modules.
  • [ ] Develop unit tests for the script generator and the new command interfaces.
  • [ ] Create a new example program demonstrating how to add a custom command (e.g., a simple gripper control).
  • [ ] Validate the new architecture by testing on real hardware.

dkar-sto avatar Jul 18 '25 08:07 dkar-sto

Thank you for the proposal. At the moment I don't see the necessary resources for that on our side, though.

urfeex avatar Sep 04 '25 12:09 urfeex

Would you consider reviewing, testing and if it passes merging a pull request, if i contribute. I would have to fork otherwise and i am not sure if i can stay up-to-date because i expect the diff to be quite large.

dkar-sto avatar Sep 04 '25 12:09 dkar-sto

In theory, yes. However, my main fear is breaking backwards compatibility with that. In that case it would definitively not be merged rightaway. If you think, you can do it in a non-breaking way I don't see a reason why not.

urfeex avatar Sep 04 '25 12:09 urfeex

i am aware that backwards compatibility is required on the public interface, if i want to get it merged. if you can help me in clarifying which parts of the driver you would consider a public interface and which parts are not crucial, this would probably help. if you can narrow the public interface down right away to some parts of the include folder, this would help. otherwise i will likely get back to you with concrete questions.

dkar-sto avatar Sep 04 '25 14:09 dkar-sto

I know that we currently don't explicitly distinguish between private and public API. So, in a way everything is public API. I think in this context mainly the API of the UrDriver class and the ScriptCommandSender class are relevant.

urfeex avatar Sep 05 '25 07:09 urfeex

@dkar-sto My mind has been coming back to this a lot lately. Though it's still a bit hard to aquire resources for this right now, I would like to draft out the design with you together, if you don't mind. Have you done on this already? Also feel free to contact me directly about this.

urfeex avatar Sep 19 '25 13:09 urfeex

Sounds great. i had to work on other things lately, so no further work was done yet on top of the idea outlined here. It's hard say for sure, as priorities may change, but i think i could start to work on this in 2 - 3 weeks.

dkar-sto avatar Sep 23 '25 05:09 dkar-sto

Sounds great. i had to work on other things lately, so no further work was done yet on top of the idea outlined here. It's hard say for sure, as priorities may change, but i think i could start to work on this in 2 - 3 weeks.

Cool! I'll try to outline my thoughts here as well, then we can maybe have a talk once you get to it.

urfeex avatar Sep 30 '25 13:09 urfeex