xArm-Developer / xarm_ros2

ROS2 developer packages for robotic products from UFACTORY
https://www.ufactory.cc/pages/xarm
BSD 3-Clause "New" or "Revised" License
125 stars 77 forks source link

TUTORIAL: How to use xarm_ros2 with the standard moveit2 `move_group` client (aka how to use `MoveitConfigsBuilder`) #87

Open gaspatxo opened 4 months ago

gaspatxo commented 4 months ago

The following launch file will launch an rviz emulated xarm7 that can be controlled through the standard move_group c++ moveit2 client. This has been tested in ROS2 Humble, tho it should work with other distribution with little to no modifications.

To make it work for your specific robot arm, you only need to modify the MoveitConfigsBuilder() arguments, which are the same as the ones described in the official documentation.

import os
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.launch_context import LaunchContext
from ament_index_python.packages import get_package_share_directory
from uf_ros_lib.moveit_configs_builder import MoveItConfigsBuilder

def generate_launch_description():

    # Load the robot configuration
    moveit_config = (
        MoveItConfigsBuilder(
            controllers_name="fake_controllers",
            ros2_control_plugin="uf_robot_hardware/UFRobotFakeSystemHardware",
            context=LaunchContext(),
            robot_type="xarm",
            dof=7
        )
        .robot_description()
        .trajectory_execution(file_path="config/xarm7/fake_controllers.yaml")
        .planning_scene_monitor(
            publish_robot_description=True, publish_robot_description_semantic=True
        )
        .planning_pipelines(pipelines=["ompl"])
        .to_moveit_configs()
    )

    run_move_group_node = Node(
        package="moveit_ros_move_group",
        executable="move_group",
        output="screen",
        parameters=[moveit_config.to_dict()],
        arguments=["--log-level", "debug"],
    )

    # RViz
    rviz_config_file = (
        get_package_share_directory("xarm_moveit_config") + "/rviz/moveit.rviz"
    )

    rviz_node = Node(
        package="rviz2",
        executable="rviz2",
        name="rviz2",
        output="log",
        arguments=["-d", rviz_config_file],
        parameters=[
            moveit_config.robot_description,
            moveit_config.robot_description_semantic,
            moveit_config.robot_description_kinematics,
            moveit_config.planning_pipelines,
            moveit_config.joint_limits,
        ],
    )

    # Static TF
    static_tf = Node(
        package="tf2_ros",
        executable="static_transform_publisher",
        name="static_transform_publisher",
        output="log",
        arguments=["--frame-id", "world", "--child-frame-id", "base_link"],
    )

    # Publish TF
    robot_state_publisher = Node(
        package="robot_state_publisher",
        executable="robot_state_publisher",
        name="robot_state_publisher",
        output="both",
        parameters=[moveit_config.robot_description],
    )

    # ros2_control using FakeSystem as hardware
    ros2_controllers_path = os.path.join(
        get_package_share_directory("xarm_controller"),
        "config",
        "xarm7_controllers.yaml",
    )

    ros2_control_node = Node(
        package="controller_manager",
        executable="ros2_control_node",
        parameters=[ros2_controllers_path],
        remappings=[
            ("/controller_manager/robot_description", "/robot_description"),
        ],
        output="both",
    )

    joint_state_broadcaster_spawner = Node(
        package="controller_manager",
        executable="spawner",
        arguments=[
            "joint_state_broadcaster",
            "--controller-manager",
            "/controller_manager",
        ],
    )

    arm_controller_spawner = Node(
        package="controller_manager",
        executable="spawner",
        arguments=["xarm7_traj_controller", "-c", "/controller_manager"],
    )

    return LaunchDescription(
        [
            rviz_node,
            static_tf,
            robot_state_publisher,
            run_move_group_node,
            ros2_control_node,
            joint_state_broadcaster_spawner,
            arm_controller_spawner,
        ]
    )

To use real hardware, only the MoveitConfigsBuilder() needs to be slightly modified:

moveit_config = (
    MoveItConfigsBuilder(
                context=LaunchContext(),
                robot_ip="192.168.1.199",
                controllers_name="controllers",
                ros2_control_plugin="uf_robot_hardware/UFRobotSystemHardware",
                robot_type="xarm",
                dof=7,
            )
            .robot_description()
            .trajectory_execution(file_path="config/xarm7/controllers.yaml")
            .planning_scene_monitor(
                publish_robot_description=True, publish_robot_description_semantic=True
            )
            .planning_pipelines(pipelines=["ompl"])
            .to_moveit_configs()
)