UniversalRobots / Universal_Robots_ROS2_Driver

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

Communication Problem with RTDEIOInterface When Used with ur_bringup #604

Open bodkal opened 1 year ago

bodkal commented 1 year ago

"Hi,

I am currently working with the interface located at https://sdurobotics.gitlab.io/ur_rtde/ and visualizing it with rviz using the command:

ros2 launch ur_bringup ur_control.launch.py ur_type:=ur10e robot_ip:=192.168.1.105 use_fake_hardware:=false launch_rviz:=true

However, I have encountered a communication problem when adding the RTDEIOInterface object. Specifically, I received the following exception message:

'Found exception One of the RTDE input registers are already in use! Currently you must disable the EtherNet/IP adapter, PROFINET, or any MODBUS unit configured on the robot. This might change in the future.'

Upon further investigation, I discovered that something in the ur_bringup is blocking the RTDEIOInterface. When I start the RTDEIOInterface before launching ur_bringup, it fails to connect to the robot.

On the other hand, ur_bringup works fine with the RTDEControlInterface and RTDEReceiveInterface objects. Do you have any suggestions for resolving this issue?"

RobertWilbrandt commented 1 year ago

You can see the list of RTDE inputs and outputs this driver uses in the rtde_input_recipe.txt and rtde_output_recipe.txt. We were already discussing adding options for this driver to not block the io registers on the robot (with the focus on allowing fieldbusses to control them while ROS moves the robot), but this has not yet been implemented.

Is there a specific reason for you to use ur_rtde next to the ROS driver instead of using the io_and_status_controller?

bodkal commented 1 year ago

I am using the ur_rtde SDK to control the robot arm, and the ROS driver for visualisation and the arm's tf. I want to use the ur_rtde_io SDK instead of the io_and_status_controller. To accomplish this, I uploaded the arm as fake hardware and opened a thread on my side that constantly publishes the arm joint values to /joint_trajectory_controller/joint_trajectory than i can use the ur_rtde_io. This solution works fine, but do you have a better suggestion?"

RobertWilbrandt commented 1 year ago

If you only use this driver for visualization, i suggest you completely ignore the driver part and only load the description. For this, take a look at ur_description/launch/view_ur.launch.py. If you only load the description and start a robot_state_publisher (so basically what that file does minus the joint_state_publisher), you should be able to publish your joint positions as sensor_msgs/msg/JointState to the /joint_states topic and see the exact current robot position.

Could this solution work for you? The advantage would be that you instantaneously see the robot position, in your solution you basically start a small robot simulation and command it to go to your current position.

bodkal commented 1 year ago

i have a bit difficult to get it works. if i launchros2 launch ur_description view_ur.launch.py ur_type:=ur10e both joint_state_publisher_node and robot_state_publisher_node , joint_state_publisher_node constantly publish his joints to /joint_states and block me to send mine.

if i run only the robot_state_publisher_node its look like no one is start the arm frames and i get for all the frames: "Warning: Invalid frame ID "wrist_1_link" passed to can Transform argument source_frame - frame does not exist" so noting happen if i send my joints to /joint_states.

if i run only the robot_state_publisher_node no one upload the arm and i cant see it on rviz.

what did i miss?

gavanderhoorn commented 1 year ago

The view_ launch file is intended to be used for viewing the URDFs.

Not for visualising the state of a real robot.

You could look at how the view_ launch file loads the xacro and starts the RSP, as that's what you need to do.

After that, do what @RobertWilbrandt suggests (ie: publish your own JointState messages on the joint_state topic). The RSP should pick those up and start broadcasting the necessary transforms.

RobertWilbrandt commented 1 year ago

That's exactly what i meant, i should have said that more clearly: Write your own launch file which only load the description and starts the robot_state_publisher.

bodkal commented 1 year ago

Thanks for helping:) I don't have a lot of experience. I edited the view_ur.launch.py and remove the joint_state_publisher node. but the frames are not loaded ("Warning: Invalid frame ID "wrist_1_link" passed to can Transform argument source_frame - frame does not exist").
is it not what @RobertWilbrandt meant?

this is the view_ur.launch.py :

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import Command, FindExecutable, LaunchConfiguration, PathJoinSubstitution
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare

def generate_launch_description():
    declared_arguments = []
    # UR specific arguments
    declared_arguments.append(
        DeclareLaunchArgument("ur_type", description="Type/series of used UR robot.")
    )
    # TODO(anyone): enable this when added into ROS2-foxy
    # choices=['ur3', 'ur3e', 'ur5', 'ur5e', 'ur10', 'ur10e', 'ur16e']))
    declared_arguments.append(
        DeclareLaunchArgument(
            "safety_limits",
            default_value="true",
            description="Enables the safety limits controller if true.",
        )
    )
    declared_arguments.append(
        DeclareLaunchArgument(
            "safety_pos_margin",
            default_value="0.15",
            description="The margin to lower and upper limits in the safety controller.",
        )
    )
    declared_arguments.append(
        DeclareLaunchArgument(
            "safety_k_position",
            default_value="20",
            description="k-position factor in the safety controller.",
        )
    )
    # General arguments
    declared_arguments.append(
        DeclareLaunchArgument(
            "description_package",
            default_value="ur_description",
            description="Description package with robot URDF/XACRO files. Usually the argument \
        is not set, it enables use of a custom description.",
        )
    )
    declared_arguments.append(
        DeclareLaunchArgument(
            "description_file",
            default_value="ur.urdf.xacro",
            description="URDF/XACRO description file with the robot.",
        )
    )
    declared_arguments.append(
        DeclareLaunchArgument(
            "prefix",
            default_value='""',
            description="Prefix of the joint names, useful for \
        multi-robot setup. If changed than also joint names in the controllers' configuration \
        have to be updated.",
        )
    )

    # Initialize Arguments
    ur_type = LaunchConfiguration("ur_type")
    safety_limits = LaunchConfiguration("safety_limits")
    safety_pos_margin = LaunchConfiguration("safety_pos_margin")
    safety_k_position = LaunchConfiguration("safety_k_position")
    # General arguments
    description_package = LaunchConfiguration("description_package")
    description_file = LaunchConfiguration("description_file")
    prefix = LaunchConfiguration("prefix")

    joint_limit_params = PathJoinSubstitution(
        [FindPackageShare(description_package), "config", ur_type, "joint_limits.yaml"]
    )
    kinematics_params = PathJoinSubstitution(
        [FindPackageShare(description_package), "config", ur_type, "default_kinematics.yaml"]
    )
    physical_params = PathJoinSubstitution(
        [FindPackageShare(description_package), "config", ur_type, "physical_parameters.yaml"]
    )
    visual_params = PathJoinSubstitution(
        [FindPackageShare(description_package), "config", ur_type, "visual_parameters.yaml"]
    )
    script_filename = PathJoinSubstitution(
        [FindPackageShare("ur_robot_driver"), "resources", "ros_control.urscript"]
    )
    input_recipe_filename = PathJoinSubstitution(
        [FindPackageShare("ur_robot_driver"), "resources", "rtde_input_recipe.txt"]
    )
    output_recipe_filename = PathJoinSubstitution(
        [FindPackageShare("ur_robot_driver"), "resources", "rtde_output_recipe.txt"]
    )

    robot_description_content = Command(
        [
            PathJoinSubstitution([FindExecutable(name="xacro")]),
            " ",
            PathJoinSubstitution([FindPackageShare(description_package), "urdf", description_file]),
            " ",
            "joint_limit_params:=",
            joint_limit_params,
            " ",
            "kinematics_params:=",
            kinematics_params,
            " ",
            "physical_params:=",
            physical_params,
            " ",
            "visual_params:=",
            visual_params,
            " ",
            "safety_limits:=",
            safety_limits,
            " ",
            "safety_pos_margin:=",
            safety_pos_margin,
            " ",
            "safety_k_position:=",
            safety_k_position,
            " ",
            "name:=",
            ur_type,
            " ",
            "script_filename:=",
            script_filename,
            " ",
            "input_recipe_filename:=",
            input_recipe_filename,
            " ",
            "output_recipe_filename:=",
            output_recipe_filename,
            " ",
            "prefix:=",
            prefix,
        ]
    )
    robot_description = {"robot_description": robot_description_content}

    rviz_config_file = PathJoinSubstitution(
        [FindPackageShare(description_package), "rviz", "view_robot.rviz"]
    )

    robot_state_publisher_node = Node(
        package="robot_state_publisher",
        executable="robot_state_publisher",
        output="both",
        parameters=[robot_description],
    )
    rviz_node = Node(
        package="rviz2",
        executable="rviz2",
        name="rviz2",
        output="log",
        arguments=["-d", rviz_config_file],
    )

    nodes_to_start = [
        robot_state_publisher_node,
        rviz_node,
    ]

    return LaunchDescription(declared_arguments + nodes_to_start)