-
Hello everyone, For the control of both robots I want a move_group node for each robot in a respective namespace e.g. ( For this I have modified xy_start.launch.py by passing The node Customised Click to expandimport os
from launch import LaunchDescription
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
from moveit_configs_utils import MoveItConfigsBuilder
import xacro
def generate_launch_description():
# =======================================================================
# NameSpace configuration
robot_name_space = "/moto_mini"
name_space_moveit = "/moto_mini_moveit"
# =======================================================================
motoman_directory = "moveit_resources_moto_motomini_moveit_config" #not Directory -> ROS Package
# URDF
motoman_robot_description_config = xacro.process_file(
os.path.join(
get_package_share_directory(motoman_directory),
"config",
"motoman_motomini.urdf.xacro",
),
)
motoman_robot_description = {
"robot_description": motoman_robot_description_config.toxml()
}
# =======================================================================
# MoveGroupNode
moveit_config = (
MoveItConfigsBuilder("moveit_resources_moto_motomini")
.robot_description(file_path="config/motoman_motomini.urdf.xacro")
.robot_description_semantic(file_path="config/motoman_motomini.srdf")
.trajectory_execution(file_path="config/moveit_controllers.yaml")
.to_moveit_configs()
)
planning_scene_monitor_parameters = {
"publish_planning_scene": True,
"publish_geometry_updates": True,
"publish_state_updates": True,
"publish_transforms_updates": True,
"publish_robot_description": True,
"publish_robot_description_semantic": True,
}
# Start the actual move_group node/action server
# robot
run_move_group_nodeX = Node(
package="moveit_ros_move_group",
executable="move_group",
namespace= name_space_moveit,
output="screen",
parameters=[
moveit_config.to_dict(),
planning_scene_monitor_parameters,
],
remappings= [
('joint_states', f'{robot_name_space}/joint_states'),
# Action -> follow_joint_trajectory action
(f'{name_space_moveit}{robot_name_space}/follow_joint_trajectory/_action/status', f'{robot_name_space}/follow_joint_trajectory/_action/status'),
(f'{name_space_moveit}{robot_name_space}/follow_joint_trajectory/_action/feedback', f'{robot_name_space}/follow_joint_trajectory/_action/feedback'),
(f'{name_space_moveit}/monitored_planning_scene', '/monitored_planning_scene'),
(f'{name_space_moveit}/display_planned_path', '/display_planned_path'),
]
)
# =======================================================================
joint_state_publisherX = Node(
package='joint_state_publisher',
executable='joint_state_publisher',
name='joint_state_publisher',
namespace= name_space_moveit,
parameters=[
{
"robot_description": motoman_robot_description,
"rate": 43,
"source_list": [f'{robot_name_space}/joint_states'],
}
],
)
# =======================================================================
robot_state_publisherX = Node(
package="robot_state_publisher",
executable="robot_state_publisher",
name="robot_state_publisher",
namespace= name_space_moveit,
parameters=[
motoman_robot_description,
{
"robot_description": motoman_robot_description,
"publish_frequency": 43.0,
"frame_prefix": "",
},
]
)
# =======================================================================
# Launch
return LaunchDescription([
run_move_group_nodeX,
joint_state_publisherX,
robot_state_publisherX,
]
) After this adjustment my ros graph looked correct again but with the new namespace: Now I wanted to test it using a script of the hello_moveit package. std::string group_name = "manipulator";
std::string move_group_namespace = "/moto_mini_moveit";
moveit::planning_interface::MoveGroupInterface::Options options(group_name, moveit::planning_interface::MoveGroupInterface::ROBOT_DESCRIPTION, move_group_namespace);
using moveit::planning_interface::MoveGroupInterface;
auto move_group_interface = MoveGroupInterface(node, options); In addition, I had to start the node via the following launch file in which I again specified the new namespace and the mapping had to be adapted. Without the launch file and running the script via ros2 run I could not even load the robot model even if I gave the argument namespace "moto_mini_moveit" to the constructor of the "hello_motomini" node. Click to expandfrom launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
name_space_moveit = "/moto_mini_moveit"
return LaunchDescription([
Node(
package='hello_moveit',
executable='hello_motomini',
name='hello_motomini',
namespace= name_space_moveit,
output="screen",
remappings= [
# Action -> move_action
('/move_action/_action/feedback', f'{name_space_moveit}/move_action/_action/feedback'),
('/move_action/_action/status', f'{name_space_moveit}/move_action/_action/status'),
# Action -> execute_trajectory ction
('/execute_trajectory/_action/feedback', f'{name_space_moveit}/execute_trajectory/_action/feedback'),
('/execute_trajectory/_action/status', f'{name_space_moveit}/execute_trajectory/_action/status'),
('/trajectory_execution_event', f'{name_space_moveit}/trajectory_execution_event'),
('/attached_collision_object', f'{name_space_moveit}/attached_collision_object'),
]
)
]) With the help of the launch file, the node started correctly and the planning was also executed. Only the execution of the trajectory fails and I don't understand why. In the Terminal of Click to expand
It seems to fail because of the following error message:
But I don't understand this, because according to rqt_graph and "ros2 node info ..." the I would appreciate any helpful input. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 18 replies
-
could you please clarify what you mean by this? Do you have both a MotoMini and a GP4 controlled by a single YRC1000? Or do you have two controllers, one for each robot? Could you please also provide more information on which version of MotoROS2 you are using? And which version of ROS 2? |
Beta Was this translation helpful? Give feedback.
-
@TE-2: have you been able to get things to work? |
Beta Was this translation helpful? Give feedback.
-
Update. @TE-2 handed over task to me. Finally, I managed to place two robots in two different moveIt nodes (namespaces). Here are my findings: I put all nodes in namespace e.g: robot_state_publisher, run_move_group_node, ros2_control_node, joint_state_publisher. After that, two main problems came up when trying to run it with previous moveIt configuration: Problem: When placing controller_manager in namespace, controller_manager wasn't visible for ros2control. Solution: Changed configuration: moto_gp4/controller_manager:
ros__parameters:
update_rate: 100 # Hz
moto_gp4:
type: joint_trajectory_controller/JointTrajectoryController
joint_state_broadcaster:
type: joint_state_broadcaster/JointStateBroadcaster
moto_gp4/moto_gp4:
...
... I don't like that I had to put namespace prefix before the name of controller_manager in ros2_controllers_namespace.yaml, but apparrently it was the only way that worked for me. (I tried many simpler things, which didn't work). Error: "action client is not connected to action server". The key was to understand how moveit_controller.yaml works. moveit_simple_controller_manager:
controller_names:
- moto_gp4
moto_gp4:
type: FollowJointTrajectory
action_ns: follow_joint_trajectory This is telling moveIt to look for action server in this path: "/moto_gp4/follow_joint_trajectory". However, its more problematic when we want to place MoveIt into new namespace... Then this "path" looks like this: "<moveit_ns>/<controller_name>/<action_ns>" (/moto_gp4/moto_gp4/follow_joint_trajectory). To solve this problem I changed the configuration of the controller manager running in namespace to following: moveit_simple_controller_manager:
controller_names:
- follow_joint_trajectory
follow_joint_trajectory:
type: FollowJointTrajectory
action_ns: "" In that case if we place the controller in namespace called "moto_gp4", we effectively end up with path: "/moto_gp4/follow_joint_trajectory", as action_ns is not defined here. Edit: launch file for reference: Click to expandimport os
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch.conditions import IfCondition, UnlessCondition
from launch_ros.actions import Node
from launch.actions import ExecuteProcess, Shutdown
from ament_index_python.packages import get_package_share_directory
from moveit_configs_utils import MoveItConfigsBuilder
import xacro
def generate_launch_description():
moveit_namespace = "moto_gp4"
moveit_namespace2 = "moto_mini"
motoman_directory = "moveit_resources_moto_gp4_moveit_config"
motoman_directory2 = "moveit_resources_moto_motomini_moveit_config"
# URDF
motoman_robot_description_config = xacro.process_file(
os.path.join(
get_package_share_directory(motoman_directory),
"config",
"motoman_gp4.urdf.xacro",
),
# mappings={'prefix': '/yaskawa_a1/'},
)
motoman_robot_description = {
"robot_description": motoman_robot_description_config.toxml()
}
# URDF
motoman_robot_description_config2 = xacro.process_file(
os.path.join(
get_package_share_directory(motoman_directory2),
"config",
"motoman_motomini.urdf.xacro",
),
# mappings={'prefix': '/yaskawa_a1/'},
)
motoman_robot_description2 = {
"robot_description": motoman_robot_description_config2.toxml()
}
moveit_config = (
MoveItConfigsBuilder("moveit_resources_moto_gp4")
.robot_description(file_path="config/motoman_gp4.urdf.xacro")
.robot_description_semantic(file_path="config/motoman_gp4.srdf")
.trajectory_execution(file_path="config/moveit_controllers_shared.yaml")
.to_moveit_configs()
)
moveit_config2 = (
MoveItConfigsBuilder("moveit_resources_moto_motomini")
.robot_description(file_path="config/motoman_motomini.urdf.xacro")
.robot_description_semantic(file_path="config/motoman_motomini.srdf")
.trajectory_execution(file_path="config/moveit_controllers_shared.yaml")
.to_moveit_configs()
)
planning_scene_monitor_parameters = {
"publish_planning_scene": True,
"publish_geometry_updates": True,
"publish_state_updates": True,
"publish_transforms_updates": True,
"publish_robot_description": True,
"publish_robot_description_semantic": True,
}
# Start the actual move_group node/action server
run_move_group_node = Node(
package="moveit_ros_move_group",
executable="move_group",
output="screen",
namespace=moveit_namespace,
parameters=[
moveit_config.to_dict(),
planning_scene_monitor_parameters,
# {"use_sim_time": True},
],
# remappings=[
# ('joint_states', 'joint_state_broadcaster/joint_states')]
)
run_move_group_node2 = Node(
package="moveit_ros_move_group",
executable="move_group",
output="screen",
namespace=moveit_namespace2,
parameters=[
moveit_config2.to_dict(),
planning_scene_monitor_parameters,
# {"use_sim_time": True},
],
# remappings=[
# ('joint_states', 'joint_state_broadcaster/joint_states')]
)
# RViz
rviz_base = os.path.join(
get_package_share_directory("moveit_resources_moto_gp4_moveit_config"), "launch"
)
rviz_full_config = os.path.join(rviz_base, "moveit_namespace.rviz")
rviz_node = Node(
package="rviz2",
executable="rviz2",
name="rviz2",
output="log",
arguments=["-d", rviz_full_config],
parameters=[
moveit_config.robot_description,
moveit_config.robot_description_semantic,
moveit_config.planning_pipelines,
moveit_config.robot_description_kinematics,
# moveit_config2.robot_description2,
# {"use_sim_time": True},
],
)
# Publish TF
robot_state_publisher = Node(
package="robot_state_publisher",
executable="robot_state_publisher",
name="robot_state_publisher",
output="both",
namespace=moveit_namespace,
parameters=[moveit_config.robot_description],
remappings=[
('joint_states', 'joint_state_broadcaster/joint_states'),
# ('/robot_description', f'/{moveit_namespace}/robot_description')
]
)
robot_state_publisher2 = Node(
package="robot_state_publisher",
executable="robot_state_publisher",
name="robot_state_publisher",
output="both",
namespace=moveit_namespace2,
parameters=[moveit_config2.robot_description],
remappings=[
('joint_states', 'joint_state_broadcaster/joint_states')
]
)
# ros2_control using FakeSystem as hardware
ros2_controllers_path = os.path.join(
get_package_share_directory("moveit_resources_moto_gp4_moveit_config"),
"config",
"ros2_controllers_shared.yaml",
)
ros2_controllers_path2 = os.path.join(
get_package_share_directory("moveit_resources_moto_motomini_moveit_config"),
"config",
"ros2_controllers_shared.yaml",
)
ros2_control_node = Node(
namespace=moveit_namespace,
package="controller_manager",
executable="ros2_control_node",
parameters=[moveit_config.robot_description, ros2_controllers_path], #Remember to add ros_control tag in xacro file
output="both",
)
ros2_control_node2 = Node(
namespace=moveit_namespace2,
package="controller_manager",
executable="ros2_control_node",
parameters=[moveit_config2.robot_description, ros2_controllers_path2], #Remember to add ros_control tag in xacro file
output="both",
)
joint_state_publisher = Node(
package='joint_state_publisher',
executable='joint_state_publisher',
name='joint_state_publisher',
namespace=moveit_namespace,
parameters=[
{
"robot_description": motoman_robot_description,
"rate": 43,
"source_list": [f'/{moveit_namespace}/joint_states'], # Könnte auch Moveit Problem sein
}
],
)
joint_state_publisher2 = Node(
package='joint_state_publisher',
executable='joint_state_publisher',
name='joint_state_publisher',
namespace=moveit_namespace2,
parameters=[
{
"robot_description": motoman_robot_description2,
"rate": 43,
"source_list": [f'/{moveit_namespace2}/joint_states'], # Könnte auch Moveit Problem sein
}
],
)
return LaunchDescription(
[
rviz_node,
# static_tf,
robot_state_publisher,
robot_state_publisher2,
run_move_group_node,
run_move_group_node2,
ros2_control_node,
ros2_control_node2,
joint_state_publisher,
joint_state_publisher2
]
) |
Beta Was this translation helpful? Give feedback.
Update. @TE-2 handed over task to me. Finally, I managed to place two robots in two different moveIt nodes (namespaces). Here are my findings:
I put all nodes in namespace e.g: robot_state_publisher, run_move_group_node, ros2_control_node, joint_state_publisher.
Only one remapping was needed for robot_state_publisher (possibly could be fixed by using different source_list at joint_state_publisher, but I didn't verify that).
After that, two main problems came up when trying to run it with previous moveIt configuration:
Problem: When placing controller_manager in namespace, controller_manager wasn't visible for ros2control.
Solution:
Changed configuration:
Add namespace prefix before contro…