Connect o3de with ur
Affected ROS2 Driver version(s)
latest
Used ROS distribution.
Other
Which combination of platform is the ROS driver running on.
Ubuntu Linux with standard kernel
How is the UR ROS2 Driver installed.
From binary packets
Which robot platform is the driver connected to.
URSim in linux, Real robot, URSim in a virtual machine, URSim in docker, UR E-series robot, UR CB3 robot
Robot SW / URSim version(s)
latest
How is the ROS driver used.
Others
Issue details
Summary
I want to use the default example of ur robot in o3de extra and move it with rviz
Issue details
In o3de-extras there is a example that include universal robot: https://github.com/o3de/o3de-extras/tree/development/Templates/Ros2RoboticManipulationTemplate. There is also a launch file but is only for panda robot. So I try to create a launch file following that one. But it does not work and my launch wait for /robot_description topic. Also there are some warning at the start that i'don't undestand why
Steps to Reproduce
download o3de and o3de-extras (latest version 2409.2). Download ur_drivere and ur_movit (latest version). Now run o3de project and run the launch file (ros2 launch my_test.launch.py ur_type:=ur10)
Expected Behavior
The flow should be the same as the provided in panda example
Actual Behavior
it doesn't work
##My launch file
import os
import yaml
from pathlib import Path
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, RegisterEventHandler
from launch.conditions import IfCondition
from launch.event_handlers import OnProcessExit
from launch.substitutions import (
LaunchConfiguration,
PathJoinSubstitution,
)
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare
from moveit_configs_utils import MoveItConfigsBuilder
from ament_index_python.packages import get_package_share_directory
from launch_ros.actions import ComposableNodeContainer
from launch_ros.descriptions import ComposableNode
def load_yaml(package_name, file_path):
package_path = get_package_share_directory(package_name)
absolute_file_path = os.path.join(package_path, file_path)
try:
with open(absolute_file_path) as file:
return yaml.safe_load(file)
except OSError: # parent of IOError, OSError *and* WindowsError where available
return None
def declare_arguments():
return LaunchDescription(
[
DeclareLaunchArgument(
"launch_rviz",
default_value="true",
description="Launch RViz?"
),
DeclareLaunchArgument(
"ur_type",
description="Typo/series of used UR robot.",
choices=[
"ur3",
"ur3e",
"ur5",
"ur5e",
"ur10",
"ur10e",
"ur16e",
"ur20",
"ur30",
],
),
DeclareLaunchArgument(
"warehouse_sqlite_path",
default_value=os.path.expanduser("~/.ros/warehouse_ros.sqlite"),
description="Path where the warehouse database should be stored",
),
DeclareLaunchArgument(
"launch_servo", default_value="false", description="Launch Servo?"
),
DeclareLaunchArgument(
"use_sim_time",
default_value="true",
description="Using or not time from simulation",
),
DeclareLaunchArgument(
"publish_robot_description_semantic",
default_value="true",
description="MoveGroup publishes robot description semantic",
),
]
)
def generate_launch_description():
launch_rviz = LaunchConfiguration("launch_rviz")
ur_type = LaunchConfiguration("ur_type")
warehouse_sqlite_path = LaunchConfiguration("warehouse_sqlite_path")
launch_servo = LaunchConfiguration("launch_servo")
use_sim_time = LaunchConfiguration("use_sim_time")
publish_robot_description_semantic = LaunchConfiguration("publish_robot_description_semantic")
moveit_config = (
MoveItConfigsBuilder(robot_name="ur", package_name="ur_moveit_config")
.robot_description_semantic(Path("srdf") / "ur.srdf.xacro", {"name": ur_type})
.to_moveit_configs()
)
warehouse_ros_config = {
"warehouse_plugin": "warehouse_ros_sqlite::DatabaseConnection",
"warehouse_host": warehouse_sqlite_path,
}
ld = LaunchDescription()
ld.add_entity(declare_arguments())
wait_robot_description = Node(
package="ur_robot_driver",
executable="wait_for_robot_description",
output="screen",
)
ld.add_action(wait_robot_description)
move_group_node = Node(
package="moveit_ros_move_group",
executable="move_group",
output="screen",
parameters=[
moveit_config.to_dict(),
warehouse_ros_config,
{
"use_sim_time": use_sim_time,
"publish_robot_description_semantic": publish_robot_description_semantic,
},
],
)
rviz_config_file = PathJoinSubstitution(
[FindPackageShare("ur_moveit_config"), "config", "moveit.rviz"]
)
rviz_node = Node(
package="rviz2",
condition=IfCondition(launch_rviz),
executable="rviz2",
name="rviz2_moveit",
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,
warehouse_ros_config,
{
"use_sim_time": use_sim_time,
},
],
)
servo_yaml = load_yaml("ur_moveit_config", "config/ur_servo.yaml")
servo_params = {"moveit_servo": servo_yaml}
servo_node = Node(
package="moveit_servo",
condition=IfCondition(launch_servo),
executable="servo_node",
parameters=[
moveit_config.to_dict(),
servo_params,
],
output="screen",
)
# Static TF
static_tf = Node(
package="tf2_ros",
executable="static_transform_publisher",
name="static_transform_publisher",
output="log",
arguments=["0.0", "0.0", "0.0", "0.0", "0.0", "0.0", "world", "panda_link0"],
)
# 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],
)
rgbd_pc = ComposableNodeContainer(
name='container0',
namespace='',
package='rclcpp_components',
executable='component_container',
composable_node_descriptions=[
ComposableNode(
package='depth_image_proc',
plugin='depth_image_proc::PointCloudXyzrgbNode',
name='point_cloud_xyzrgb_node',
remappings=[('rgb/camera_info', '/color_camera_info'),
('rgb/image_rect_color', '/camera_image_color'),
('depth_registered/image_rect','/camera_image_depth'),
('/points','/pointcloud')]
),
],
output='screen',
parameters=[{'use_sim_time': True}],
)
ld.add_action(
RegisterEventHandler(
OnProcessExit(
target_action=wait_robot_description,
on_exit=[
move_group_node,
rviz_node,
servo_node,
static_tf,
robot_state_publisher,
rgbd_pc,
],
)
),
)
return ld
Relevant log output
[INFO] [launch]: All log files can be found below /home/robx/.ros/log/2025-03-05-19-35-14-534067-robx-MS-7D67-316208
[INFO] [launch]: Default logging verbosity is set to INFO
WARNING:root:Cannot infer URDF from `/opt/ros/jazzy/share/ur_moveit_config`. -- using config/ur.urdf
WARNING:root:Cannot infer SRDF from `/opt/ros/jazzy/share/ur_moveit_config`. -- using config/ur.srdf
WARNING:root:"File /opt/ros/jazzy/share/ur_moveit_config/config/ur.urdf doesn't exist"
WARNING:root:The robot description will be loaded from /robot_description topic
[INFO] [wait_for_robot_description-1]: process started with pid [316211]
[wait_for_robot_description-1] [INFO] [1741199714.811761162] [wait_for_robot_description]: Waiting for message on /robot_description.
Accept Public visibility
- [x] I agree to make this context public
Hi, thank you for reaching out. We appreciate that you try to use other simulators with a UR robot. However, at the moment we only support Gazebo as a simulator.
However, your questions seems more to be related to your custom launch file than the the simulator. Please understand that we also cannot help individual problems when creating custom integrations. Looking at your output, however, it seems that the move_group / the helper node is waiting for the robot description being published. In the driver launch that comes from the robot_state publisher launched in rsp.launch.py.
I don't know how o3de integrates with a URDF / robot_description, so this could be wrong advice. You can also make the move_group load the description. For that, it is easiest to create a custom moveit support package using the moveit setup assistant. The default launchfiles generated from that will load the description. See out custom workcell tutorial on details for that.
The main difference between O3DE and Gazebo is that O3DE does not publish robot descriptions on /robot_description topic.
The ur_moveit.launch.py script worked fine on ROS 2 Humble (humble branch) without getting any information on the topic, but it was refactored on the main branch and this information is required. I do not know the history behind this change, but we do not have the resources in the O3DE community to maintain the launchers of other robots, as we focus on developing the engine itself. The information about UR robots will be removed from the O3DE documentation.