Set Tool I/O with ROS2

I`m using ROS2 Humble and the UR_Driver.

I try to Set the Tool I/O of my UR3e.
I already figured out how to set them with the Terminal.

ros2 service call /io_and_status_controller/set_io ur_msgs/srv/SetIO "{fun: 1, pin: 17, state: 1}" 

Now i try to Set them with my custom Script in my custom workspace.
I assume it has to work similar to the Client in the tutorial. But i struggle a little with what to include and how to substitude the AddTwoInts.

Can someone help me out on this?

Hi,

welcome to the world of ROS(2). You’ll first have to import the service definition:

from ur_msgs.srv import SetIO

The rest should be fairly straight forward

    def send_request(self, a, b):
        self.req.fun = SetIO.FUN_SET_DIGITAL_OUT # Prefer using constants instead of writing the constant's value
        self.req.pin = 17
        self.state = 1
        ...

I hope, this helps.

Thank you

i wrote the Client like this:

from ur_msgs.srv import SetIO
import rclpy
from rclpy.node import Node


class IOClient(Node):

    def __init__(self):
        super().__init__('client_test')
        self.cli = self.create_client(SetIO, 'set_i_o')
        while not self.cli.wait_for_service(timeout_sec=1.0):
            self.get_logger().info('service not available, waiting again...')
        self.req = SetIO.Request()

    def send_request(self):
        self.req.fun = SetIO.FUN_SET_DIGITAL_OUT # Prefer using constants instead of writing the constant's value
        self.req.pin = SetIO.PIN_TOOL_DOUT1
        self.req.state = SetIO.STATE_ON 

        self.future = self.cli.call_async(self.req)
        rclpy.spin_until_future_complete(self, self.future)
        


def main():
    rclpy.init()

    IOclient = IOClient()
    IOclient.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()

I also added <depend>ur_msgs</depend> in package.xml
and in setup.py i added 'console_scripts': [ 'client=client_test.client_test:main'].

after colcon build and source insatll/setup.bash i run ros2 run client_test client

and get this output

Traceback (most recent call last):
  File "/home/luca/workspace/ur_control/install/client_test/lib/client_test/client", line 33, in <module>
    sys.exit(load_entry_point('client-test==0.0.0', 'console_scripts', 'client')())
  File "/home/luca/workspace/ur_control/install/client_test/lib/client_test/client", line 25, in importlib_load_entry_point
    return next(matches).load()
  File "/usr/lib/python3.10/importlib/metadata/__init__.py", line 171, in load
    module = import_module(match.group('module'))
  File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1004, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'client_test.client_test'
[ros2run]: Process exited with failure 1

My path looks like this: ~workspace/ur_control/src/client_test/src/client_test.py
My package is called client_test and my file is called client_test.py

I had to move the file to my client_test folder with my empty __init__.py in there.

Now the file is executeable but it cant connect to the service.

[INFO] [1666702583.137077628] [client_test]: service not available, waiting again...

But with

ros2 service call /io_and_status_controller/set_io ur_msgs/srv/SetIO "{fun: 1, pin: 17, state: 1}

i can set the DO.

This creates a service client for the service running on /set_i_o This service does not exist, since it lives in /io_and_status_controller/set_io.

Please note, that such common questions are better asked on answers.ros.org. There will be a broader audience being able to help you with your problems getting started with ROS.

Ok
Thank you for you help