ICube-Robotics / ethercat_driver_ros2

Hardware Interface for EtherCAT module integration with ros2_control
https://icube-robotics.github.io/ethercat_driver_ros2/
Apache License 2.0
126 stars 32 forks source link

example urdf, controller and launch file #14

Closed ros2torial closed 1 year ago

ros2torial commented 1 year ago

Hi, Can you please provide a example urdf, controller and launch file for getting started with the GPIO controller.

I am having EK1100 EtherCAT Coupler, EL1008 and EL2008 module and trying to create a gpio control using this repo and gpio_controllers package mentioned in the doc.

I created this urdf file


<?xml version="1.0" ?>

<robot name="gpio" xmlns:xacro="http://ros.org/wiki/xacro">

  <ros2_control name="mySystem" type="system">

    <hardware>
        <plugin>ethercat_driver/EthercatDriver</plugin>
        <param name="master_id">0</param>
        <param name="control_frequency">100</param>
    </hardware>
    <gpio name="gpio1">
      <state_interface name="dig_input.1"/>
      <state_interface name="dig_input.2"/>
      <state_interface name="dig_input.3"/>
      <state_interface name="dig_input.4"/>
      <state_interface name="dig_input.5"/>
      <state_interface name="dig_input.6"/>
      <state_interface name="dig_input.7"/>
      <state_interface name="dig_input.8"/>
      <ec_module name="EL1008">
          <plugin>ethercat_plugins/Beckhoff_EL1008</plugin>
          <param name="alias">0</param>
          <param name="position">1</param>
          <param name="di.1">dig_input.1</param>
          <param name="di.2">dig_input.2</param>
          <param name="di.3">dig_input.3</param>
          <param name="di.4">dig_input.4</param>
          <param name="di.5">dig_input.5</param>
          <param name="di.6">dig_input.6</param>
          <param name="di.7">dig_input.7</param>
          <param name="di.8">dig_input.8</param>
      </ec_module>
    </gpio>
    <gpio name="gpio2">
      <command_interface name="dig_output.1"/>
      <command_interface name="dig_output.2"/>
      <command_interface name="dig_output.3"/>
      <command_interface name="dig_output.4"/>
      <command_interface name="dig_output.5"/>
      <command_interface name="dig_output.6"/>
      <command_interface name="dig_output.7"/>
      <command_interface name="dig_output.8"/>
      <state_interface name="dig_output.1"/>
      <state_interface name="dig_output.2"/>
      <state_interface name="dig_output.3"/>
      <state_interface name="dig_output.4"/>
      <state_interface name="dig_output.5"/>
      <state_interface name="dig_output.6"/>
      <state_interface name="dig_output.7"/>
      <state_interface name="dig_output.8"/>
      <ec_module name="EL2008">
          <plugin>ethercat_plugins/Beckhoff_EL2008</plugin>
          <param name="alias">0</param>
          <param name="position">2</param>
          <param name="do.1">dig_output.1</param>
          <param name="do.2">dig_output.2</param>
          <param name="do.3">dig_output.3</param>
          <param name="do.4">dig_output.4</param>
          <param name="do.5">dig_output.5</param>
          <param name="do.6">dig_output.6</param>
          <param name="do.7">dig_output.7</param>
          <param name="do.8">dig_output.8</param>
      </ec_module>
    </gpio>

  </ros2_control>

</robot>

and this controller file

controller_manager:
  ros__parameters:
    update_rate: 100  # Hz

    gpio_command_controller:
      type: gpio_controllers/GpioCommandController

gpio_command_controller:
  ros__parameters:
    gpios:
      - gpio1
      - gpio2
    state_interfaces:
      gpio1:
        - dig_input.1
        - dig_input.2
        - dig_input.3
        - dig_input.4
        - dig_input.5
        - dig_input.6
        - dig_input.7
        - dig_input.8
      gpio2:
        - dig_output.1
        - dig_output.2
        - dig_output.3
        - dig_output.4
        - dig_output.5
        - dig_output.6
        - dig_output.7
        - dig_output.8
    command_interfaces:
      gpio2:
        - dig_output.1
        - dig_output.2
        - dig_output.3
        - dig_output.4
        - dig_output.5
        - dig_output.6
        - dig_output.7
        - dig_output.8

and the launch file


from launch import LaunchDescription
from launch.substitutions import PathJoinSubstitution
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare

def generate_launch_description():

    urdf_path = PathJoinSubstitution([FindPackageShare('gpio_control'), 'urdf', 'gpio_ros2_control.urdf'])
    gpio_controller_path = PathJoinSubstitution([FindPackageShare('gpio_control'), 'config', 'gpio_controller.yaml'])
    robot_description = {"robot_description": urdf_path}

    ros2_control_node = Node(
        package='controller_manager',
        executable='ros2_control_node',
        parameters=[robot_description, gpio_controller_path],
        output='screen',
    )

    gpio_controller_node = Node(
        package='controller_manager',
        executable='spawner',
        arguments=['gpio_controller'],
        output='screen',
    )

    # Create the launch description and populate
    ld = LaunchDescription()

    # declared_arguments

    # nodes_to_start
    ld.add_action(ros2_control_node)
    ld.add_action(gpio_controller_node)

    return ld

After running the control launch file i get this error

[INFO] [ros2_control_node-1]: process started with pid [18083] [INFO] [spawner-2]: process started with pid [18085] [ros2_control_node-1] terminate called after throwing an instance of 'std::runtime_error' [ros2_control_node-1] what(): invalid URDF passed in to robot parser [ERROR] [ros2_control_node-1]: process has died [pid 18083, exit code -6

mcbed commented 1 year ago

Hi, Your problem is probably caused by not using xacro and using its description tag

<robot name="gpio" xmlns:xacro="http://ros.org/wiki/xacro">

which needs to be interpreted first. Try with

robot_description_content = Command(
        [
            PathJoinSubstitution([FindExecutable(name='xacro')]),
            ' ',
            PathJoinSubstitution(
                [FindPackageShare('gpio_control'), 'urdf', 'gpio_ros2_control.urdf']
            ),
        ]
    )
robot_description = {'robot_description': robot_description_content}
ros2torial commented 1 year ago

Thanks @mcbed , it worked.

Actually previously it was xacro only. there was some issue so i changed it to urdf as the file was simple so it should have worked. I even removed xmlns:xacro="http://ros.org/wiki/xacro" part but the normal urdf launch didn't work. Anyways the above method worked.

Thanks again!!

boilerbots commented 1 year ago

This didn't work for me when i tried it because the code expects anything defined under "gpios" to also be defined under command_interfaces, you will get an error because "gpio1" is not defined. It doesn't work correctly for me when trying to mix state_interfaces and command_interfaces.

This could be because the code is undergoing changes, thought I would leave a comment in case someone else finds this and attempts to use this as reference.