UniversalRobots / Universal_Robots_ROS2_Driver

Universal Robots ROS2 driver supporting CB3 and e-Series
BSD 3-Clause "New" or "Revised" License
364 stars 185 forks source link

Add support for send custom script commands to robot #251

Closed urrsk closed 11 months ago

urrsk commented 2 years ago

As in the ROS1 driver using the client_library

sillkjc commented 1 year ago

I'd like to upvote this as a super important feature I really need. There are many thing that need to be done via string substituted ur scripts that then get sent to the robot. It can also greatly simplify rapid testing / prototyping. It would enable workarounds for a lot of the missing features to meet ROS1 feature parity.

bmdyrdal commented 1 year ago

Is there any update on this?

urrsk commented 1 year ago

@bmdyrdal to my understanding, ros2_control are still limiting us for doing this. @destogl please correct me if I am wrong But I agree that this is a need to have feature

bmdyrdal commented 1 year ago

@urrsk Thanks for the update. Any recommended ways for working around this?

urrsk commented 1 year ago

@bmdyrdal you can modify the UR script the ROS driver/Client library are using and in this way you can adjust it to your needs. See https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/dfa1410653ebcb57f3522491f61a4d6344425056/ur_bringup/launch/ur_control.launch.py#L84

What would you like to do?

bmdyrdal commented 1 year ago

@urrsk Aha, I see. Thank you! We currently use it during initialization to position the robot correctly and set some output values. As we also needed to read and write registers we've ended up porting our fork of ur_rtde to ROS2 instead.

sillkjc commented 1 year ago

We've found one semi workaround is to write some scripts that SCP a .URP file and .script file to the robot, with the URP being an empty .script command. We can then use the load_program service to load and run it.

We had to make a custom docker extend to the ur_sim docker container to turn on the SCP server.

This comes with one crippling drawback - load_program also calls load_installation, so the installation from the URP is loaded.

This resets the currently set tcp/cog/mass safetly limits, home position etc, for each script sent. This makes it not really an option for real hardware.

Still hoping for a 'run_script' service, we added this to the ROS1 UR driver and it proved super useful. This really should have been added before most other services, since you can achieve anything required using scripts.

urrsk commented 1 year ago

@sillkjc If you want the robot to only run your own URScript code, then you do not need Polyscope or ROS.

The robot controller accept receiving URScript directly and can received it through a ascii socket connection, though you need to set the Robot in Remote control mode. (Do not be surprised then you connect the the primary or secondary protocol, as there is a lot of data send from the robot through this port as well.)
See https://forum.universal-robots.com/t/communication-interfaces/29' and https://myur.universal-robots.com/manuals/content/SW_5_13/Documentation%20Menu/Script%20Manual/Connecting%20to%20URControl

You can also do as we do in the ROS driver and use the External Control URCap to send the URScrip or inject it into the Polyscope program. The ROS driver is using this implemented with the ScriptSender class from the Client library.

sillkjc commented 1 year ago

We want this to work alongside the UR driver. We use a hybrid of Moveit moves (via ros2_control) as well as UR Script commands. The general pattern is you can use moveit to move for large unstructured movements. Then when in proximity to a work object, you hand over control to UR scripts to perform small unchecked moves, fire IO's, check IO's, force control or screwdriver caps etc. It's important to be able to send UR scripts whilst leaving the ROS UR driver connected and functioning once the script is finished.

This is the way the ROS1 driver worked, but in place of the ROS2 control integration it was instead using the RTDE socket to stream joint trajectories.

sillkjc commented 1 year ago

I think the main idea is the UR driver should handle connecting to sockets 1, 2 and 3. It should then also provide an interface to stream scripts line by line, read from a file, invoked via service call.

It makes little sense to write a second client to do this. As soon as the second clients script activates it will cancel the UR drivers running script, and the UR driver will loose connection.

Edit: I may be under the misconception that it will halt the primary program. Either way it makes sense to be part of the driver.

bmdyrdal commented 1 year ago

@sillkjc We ended up creating a simple Action server that sends the script on the Primary client interface, port: 30001. This works well for us :) If you want to monitor the states of the script you can add some return values to I/O's.

sillkjc commented 1 year ago

@sillkjc We ended up creating a simple Action server that sends the script on the Primary client interface, port: 30001. This works well for us :) If you want to monitor the states of the script you can add some return values to I/O's.

This sounds like what we may end up doing. We have a 'URScriptClient' python class that handles formatting script commands for common moves, taking ros geometry types as input. It would be a good class to integrate the ActionServer into. If its python, it may save us some time if you could share the Action Server.

bmdyrdal commented 1 year ago

@sillkjc We ended up creating a simple Action server that sends the script on the Primary client interface, port: 30001. This works well for us :) If you want to monitor the states of the script you can add some return values to I/O's.

This sounds like what we may end up doing. We have a 'URScriptClient' python class that handles formatting script commands for common moves, taking ros geometry types as input. It would be a good class to integrate the ActionServer into. If its python, it may save us some time if you could share the Action Server.

Sorry, I'm not allowed to share the code :( But it's fairly similar to the examples for ActionServers, just with the addition of some handling of if the robot is running or not and the return values through IO's.

urrsk commented 1 year ago

Good that you are not blocked by this. I agree that it could be nice to get this script interface into the ROS2 driver as well. Though ros2_control is not yet ready to support this.

An alternative is that you can extend and adjust the URScript files that the ROS drivers and Client library is using. It is possible to launch the ROS drivers with custom script files. See the launch files and the URScript file