diff --git a/nexus_integration_tests/config/office/tinyRobot_config.yaml b/nexus_integration_tests/config/office/tinyRobot_config.yaml deleted file mode 100644 index 75d53a7..0000000 --- a/nexus_integration_tests/config/office/tinyRobot_config.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# FLEET CONFIG ================================================================= -# RMF Fleet parameters - -rmf_fleet: - name: "tinyRobot" - limits: - linear: [0.5, 0.75] # velocity, acceleration - angular: [0.6, 2.0] # velocity, acceleration - profile: # Robot profile is modelled as a circle - footprint: 0.3 # radius in m - vicinity: 0.5 # radius in m - reversible: True # whether robots in this fleet can reverse - battery_system: - voltage: 12.0 # V - capacity: 24.0 # Ahr - charging_current: 5.0 # A - mechanical_system: - mass: 20.0 # kg - moment_of_inertia: 10.0 #kgm^2 - friction_coefficient: 0.22 - ambient_system: - power: 20.0 # W - tool_system: - power: 0.0 # W - recharge_threshold: 0.10 # Battery level below which robots in this fleet will not operate - recharge_soc: 1.0 # Battery level to which robots in this fleet should be charged up to during recharging tasks - publish_fleet_state: 10.0 # Publish frequency for fleet state, ensure that it is same as robot_state_update_frequency - account_for_battery_drain: True - task_capabilities: # Specify the types of RMF Tasks that robots in this fleet are capable of performing - loop: True - delivery: True - actions: ["teleop"] - finishing_request: "park" # [park, charge, nothing] - responsive_wait: True # Should responsive wait be on/off for the whole fleet by default? False if not specified. - reassign_task_interval: 120 # seconds, specify how often a task reassignment should be triggered in the fleet - robots: - tinyRobot1: - charger: "tinyRobot1_charger" - responsive_wait: False # Should responsive wait be on/off for this specific robot? Overrides the fleet-wide setting. - tinyRobot2: - charger: "tinyRobot2_charger" - # No mention of responsive_wait means the fleet-wide setting will be used - -fleet_manager: - ip: "127.0.0.1" - port: 22011 - user: "some_user" - password: "some_password" diff --git a/nexus_integration_tests/config/rmf/depot_scan.png b/nexus_integration_tests/config/rmf/depot_scan.png new file mode 100644 index 0000000..bfc74d9 Binary files /dev/null and b/nexus_integration_tests/config/rmf/depot_scan.png differ diff --git a/nexus_integration_tests/config/rmf_bts/transportation.xml b/nexus_integration_tests/config/rmf/transportation.xml similarity index 100% rename from nexus_integration_tests/config/rmf_bts/transportation.xml rename to nexus_integration_tests/config/rmf/transportation.xml diff --git a/nexus_integration_tests/launch/depot.launch.xml b/nexus_integration_tests/launch/depot.launch.xml deleted file mode 100644 index ad4635f..0000000 --- a/nexus_integration_tests/launch/depot.launch.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/nexus_integration_tests/launch/control_center.launch.py b/nexus_integration_tests/launch/inter_workcell.launch.py similarity index 74% rename from nexus_integration_tests/launch/control_center.launch.py rename to nexus_integration_tests/launch/inter_workcell.launch.py index c0cb2f2..57c3897 100644 --- a/nexus_integration_tests/launch/control_center.launch.py +++ b/nexus_integration_tests/launch/inter_workcell.launch.py @@ -106,6 +106,8 @@ def activate_node(target_node: LifecycleNode, depend_node: LifecycleNode = None) def launch_setup(context, *args, **kwargs): ros_domain_id = LaunchConfiguration("ros_domain_id") + use_fake_hardware = LaunchConfiguration("use_fake_hardware") + use_rmf_transporter = LaunchConfiguration("use_rmf_transporter") use_zenoh_bridge = LaunchConfiguration("use_zenoh_bridge") zenoh_config_package = LaunchConfiguration("zenoh_config_package") zenoh_config_filename = LaunchConfiguration("zenoh_config_filename") @@ -115,8 +117,11 @@ def launch_setup(context, *args, **kwargs): main_bt_filename = LaunchConfiguration("main_bt_filename") remap_task_types = LaunchConfiguration("remap_task_types") + rviz_config_filename = "nexus_panel.rviz" + if (use_rmf_transporter.perform(context).lower() == "true"): + rviz_config_filename = "nexus_panel_rmf.rviz" nexus_panel_rviz_path = os.path.join( - get_package_share_directory("nexus_integration_tests"), "rviz", "nexus_panel.rviz" + get_package_share_directory("nexus_integration_tests"), "rviz", rviz_config_filename ) system_orchestrator_node = LifecycleNode( @@ -137,6 +142,27 @@ def launch_setup(context, *args, **kwargs): ], ) + rmf_transporter = GroupAction( + actions=[ + IncludeLaunchDescription( + [ + PathJoinSubstitution( + [ + FindPackageShare("nexus_integration_tests"), + "launch", + "rmf_transporter.launch.xml", + ] + ) + ], + launch_arguments={ + "use_simulator": use_fake_hardware, + "headless": headless, + }.items(), + condition=IfCondition(use_rmf_transporter), + ) + ], + ) + transporter_node = LifecycleNode( namespace="", package="nexus_transporter", @@ -149,6 +175,14 @@ def launch_setup(context, *args, **kwargs): {"speed": 1.0}, {"unloading_station": "unloading"}, ], + condition=UnlessCondition(use_rmf_transporter), + ) + + activate_transporter_node = GroupAction( + [ + activate_node(transporter_node), + ], + condition=UnlessCondition(use_rmf_transporter), ) mock_emergency_alarm_node = LifecycleNode( @@ -166,40 +200,45 @@ def launch_setup(context, *args, **kwargs): condition=UnlessCondition(headless), ) + zenoh_bridge = GroupAction( + [ + IncludeLaunchDescription( + [ + PathJoinSubstitution( + [ + FindPackageShare("nexus_integration_tests"), + "launch", + "zenoh_bridge.launch.py", + ] + ) + ], + launch_arguments={ + "zenoh_config_package": zenoh_config_package, + "zenoh_config_filename": zenoh_config_filename, + "ros_domain_id": ros_domain_id.perform(context), + }.items(), + ) + ], + condition=IfCondition(use_zenoh_bridge), + ) + + activate_system_orchestrator = GroupAction( + [ + activate_node(system_orchestrator_node), + ], + condition=IfCondition(activate_system_orchestrator), + ) + return [ SetEnvironmentVariable("ROS_DOMAIN_ID", ros_domain_id), system_orchestrator_node, + rmf_transporter, transporter_node, mock_emergency_alarm_node, nexus_panel, - GroupAction( - [ - IncludeLaunchDescription( - [ - PathJoinSubstitution( - [ - FindPackageShare("nexus_integration_tests"), - "launch", - "zenoh_bridge.launch.py", - ] - ) - ], - launch_arguments={ - "zenoh_config_package": zenoh_config_package, - "zenoh_config_filename": zenoh_config_filename, - "ros_domain_id": ros_domain_id.perform(context), - }.items(), - ) - ], - condition=IfCondition(use_zenoh_bridge), - ), - GroupAction( - [ - activate_node(system_orchestrator_node), - ], - condition=IfCondition(activate_system_orchestrator), - ), - activate_node(transporter_node), + zenoh_bridge, + activate_system_orchestrator, + activate_transporter_node, activate_node(mock_emergency_alarm_node), ] @@ -213,6 +252,17 @@ def generate_launch_description(): default_value="0", description="ROS_DOMAIN_ID environment variable", ), + DeclareLaunchArgument( + "use_fake_hardware", + default_value="true", + description="Set True if running with real hardware.", + ), + DeclareLaunchArgument( + "use_rmf_transporter", + default_value="false", + description="Set true to rely on an Open-RMF managed fleet to transport material\ + between workcells.", + ), DeclareLaunchArgument( "use_zenoh_bridge", default_value="true", diff --git a/nexus_integration_tests/launch/launch.py b/nexus_integration_tests/launch/launch.py index ff4567b..32adad0 100644 --- a/nexus_integration_tests/launch/launch.py +++ b/nexus_integration_tests/launch/launch.py @@ -41,6 +41,7 @@ def launch_setup(context, *args, **kwargs): exit(1) headless = LaunchConfiguration("headless") + use_rmf_transporter = LaunchConfiguration("use_rmf_transporter") use_zenoh_bridge = LaunchConfiguration("use_zenoh_bridge") use_fake_hardware = LaunchConfiguration("use_fake_hardware") robot1_ip = LaunchConfiguration("robot1_ip") @@ -48,23 +49,23 @@ def launch_setup(context, *args, **kwargs): run_workcell_1 = LaunchConfiguration("run_workcell_1") run_workcell_2 = LaunchConfiguration("run_workcell_2") - control_center_domain_id = 0 + inter_workcell_domain_id = 0 workcell_1_domain_id = 0 workcell_2_domain_id = 0 log_msg = "" if "ROS_DOMAIN_ID" in os.environ: - control_center_domain_id = int(os.environ["ROS_DOMAIN_ID"]) - if not 0 < control_center_domain_id < 230: + inter_workcell_domain_id = int(os.environ["ROS_DOMAIN_ID"]) + if not 0 < inter_workcell_domain_id < 230: log_msg += ( "ROS_DOMAIN_ID not within the range of 0 to 230, setting it to 0. \n" ) - control_center_domain_id = 0 + inter_workcell_domain_id = 0 if use_zenoh_bridge.perform(context).lower() == "true": log_msg += "Using the zenoh bridge\n" - workcell_1_domain_id = control_center_domain_id + 1 - workcell_2_domain_id = control_center_domain_id + 2 + workcell_1_domain_id = inter_workcell_domain_id + 1 + workcell_2_domain_id = inter_workcell_domain_id + 2 else: log_msg += "Not using zenoh bridge\n" if ( @@ -73,15 +74,20 @@ def launch_setup(context, *args, **kwargs): ): print("To run both workcells, enable the Zenoh Bridge") sys.exit(1) - workcell_1_domain_id = control_center_domain_id - workcell_2_domain_id = control_center_domain_id - log_msg += f"Control Center has ROS_DOMAIN_ID {control_center_domain_id}\n" + workcell_1_domain_id = inter_workcell_domain_id + workcell_2_domain_id = inter_workcell_domain_id + log_msg += f"Inter-workcell has ROS_DOMAIN_ID {inter_workcell_domain_id}\n" if run_workcell_1.perform(context).lower() == "true": log_msg += f"Workcell 1 has ROS_DOMAIN_ID {workcell_1_domain_id}\n" if run_workcell_2.perform(context).lower() == "true": log_msg += f"Workcell 2 has ROS_DOMAIN_ID {workcell_2_domain_id}\n" - launch_control_center = GroupAction( + main_bt_filename = "main.xml" + if (use_rmf_transporter.perform(context).lower() == "true"): + main_bt_filename = "main_rmf.xml" + log_msg += f"System Orchestrator will load : {main_bt_filename}\n" + + launch_inter_workcell = GroupAction( actions=[ IncludeLaunchDescription( [ @@ -89,17 +95,19 @@ def launch_setup(context, *args, **kwargs): [ FindPackageShare("nexus_integration_tests"), "launch", - "control_center.launch.py", + "inter_workcell.launch.py", ] ) ], launch_arguments={ - "ros_domain_id": str(control_center_domain_id), + "ros_domain_id": str(inter_workcell_domain_id), "zenoh_config_package": "nexus_integration_tests", "zenoh_config_filename": "config/zenoh/system_orchestrator.json5", + "use_rmf_transporter": use_rmf_transporter, "transporter_plugin": "nexus_transporter::MockTransporter", "activate_system_orchestrator": headless, "headless": headless, + "main_bt_filename": main_bt_filename, }.items(), ), ], @@ -193,7 +201,7 @@ def launch_setup(context, *args, **kwargs): return [ LogInfo(msg=log_msg), - launch_control_center, + launch_inter_workcell, launch_workcell_1, launch_workcell_2, ] @@ -207,6 +215,12 @@ def generate_launch_description(): default_value="true", description="Launch in headless mode (no gui)", ), + DeclareLaunchArgument( + "use_rmf_transporter", + default_value="false", + description="Set true to rely on an Open-RMF managed fleet to transport material\ + between workcells.", + ), DeclareLaunchArgument( "use_zenoh_bridge", default_value="true", diff --git a/nexus_integration_tests/launch/rmf/common.launch.xml b/nexus_integration_tests/launch/rmf/common.launch.xml deleted file mode 100644 index 8e928b6..0000000 --- a/nexus_integration_tests/launch/rmf/common.launch.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/nexus_integration_tests/launch/rmf/simulation.launch.xml b/nexus_integration_tests/launch/rmf/simulation.launch.xml deleted file mode 100644 index d6cb172..0000000 --- a/nexus_integration_tests/launch/rmf/simulation.launch.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/nexus_integration_tests/launch/rmf_transporter.launch.xml b/nexus_integration_tests/launch/rmf_transporter.launch.xml new file mode 100644 index 0000000..7b66c9e --- /dev/null +++ b/nexus_integration_tests/launch/rmf_transporter.launch.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nexus_integration_tests/package.xml b/nexus_integration_tests/package.xml index 59117b5..3459225 100644 --- a/nexus_integration_tests/package.xml +++ b/nexus_integration_tests/package.xml @@ -36,14 +36,26 @@ launch launch_ros launch_xml + + nexus_capabilities nexus_motion_planner nexus_rviz_plugins nexus_system_orchestrator nexus_workcell_orchestrator nexus_zenoh_bridge_dds_vendor + + + rmf_building_map_tools rmf_demos_fleet_adapter rmf_robot_sim_gz_plugins + rmf_task_ros2 + rmf_traffic_ros2 + rmf_visualization + + + gz_sim_vendor + ros_gz_bridge ament_cmake_catch2 ament_index_cpp diff --git a/nexus_integration_tests/rviz/nexus_panel_rmf.rviz b/nexus_integration_tests/rviz/nexus_panel_rmf.rviz new file mode 100644 index 0000000..d2cbafc --- /dev/null +++ b/nexus_integration_tests/rviz/nexus_panel_rmf.rviz @@ -0,0 +1,251 @@ +Panels: + - Class: rviz_common/Displays + Help Height: 138 + Name: Displays + Property Tree Widget: + Expanded: + - /Global Options1 + - /Status1 + - /MarkerArray1 + - /MarkerArray1/Topic1 + - /MarkerArray2 + - /MarkerArray2/Topic1 + - /MarkerArray3 + - /MarkerArray3/Topic1 + - /MarkerArray4 + - /MarkerArray4/Topic1 + - /Map1 + - /Map1/Status1 + - /Map1/Topic1 + Splitter Ratio: 0.5 + Tree Height: 226 + - Class: rviz_common/Selection + Name: Selection + - Class: rviz_common/Tool Properties + Expanded: + - /2D Goal Pose1 + - /Publish Point1 + Name: Tool Properties + Splitter Ratio: 0.5886790156364441 + - Class: rviz_common/Views + Expanded: + - /Current View1 + Name: Views + Splitter Ratio: 0.5 + - Class: rviz_common/Time + Experimental: false + Name: Time + SyncMode: 0 + SyncSource: "" + - Class: nexus_rviz_plugins/NEXUSPanel + Name: NEXUSPanel + - Class: rmf_visualization_rviz2_plugins/SchedulePanel + Finish: 600 + Map: L1 + Name: SchedulePanel + Topic: /rmf_visualization/parameters +Visualization Manager: + Class: "" + Displays: + - Alpha: 0.5 + Cell Size: 1 + Class: rviz_default_plugins/Grid + Color: 160; 160; 164 + Enabled: true + Line Style: + Line Width: 0.029999999329447746 + Value: Lines + Name: Grid + Normal Cell Count: 0 + Offset: + X: 0 + Y: 0 + Z: 0 + Plane: XY + Plane Cell Count: 10 + Reference Frame: + Value: true + - Class: rviz_default_plugins/TF + Enabled: true + Filter (blacklist): "" + Filter (whitelist): "" + Frame Timeout: 600 + Frames: + All Enabled: true + deliveryRobot1/base_link: + Value: true + deliveryRobot2/base_link: + Value: true + world: + Value: true + Marker Scale: 1 + Name: TF + Show Arrows: true + Show Axes: true + Show Names: true + Tree: + world: + deliveryRobot1/base_link: + {} + deliveryRobot2/base_link: + {} + Update Interval: 0 + Value: true + - Class: rviz_default_plugins/MarkerArray + Enabled: true + Name: MarkerArray + Namespaces: + body: true + name: true + nose: true + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /fleet_markers + Value: true + - Class: rviz_default_plugins/MarkerArray + Enabled: true + Name: MarkerArray + Namespaces: + {} + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /schedule_markers + Value: true + - Class: rviz_default_plugins/MarkerArray + Enabled: true + Name: MarkerArray + Namespaces: + deliveryRobot/labels/L1: true + deliveryRobot/lanes/L1: true + deliveryRobot/waypoints/L1: true + Topic: + Depth: 5 + Durability Policy: Transient Local + History Policy: Keep Last + Reliability Policy: Reliable + Value: /map_markers + Value: true + - Class: rviz_default_plugins/MarkerArray + Enabled: true + Name: MarkerArray + Namespaces: + {} + Topic: + Depth: 5 + Durability Policy: Transient Local + History Policy: Keep Last + Reliability Policy: Reliable + Value: /building_systems_markers + Value: true + - Alpha: 0.699999988079071 + Binary representation: false + Binary threshold: 100 + Class: rviz_default_plugins/Map + Color Scheme: map + Draw Behind: false + Enabled: true + Name: Map + Topic: + Depth: 5 + Durability Policy: Transient Local + Filter size: 10 + History Policy: Keep Last + Reliability Policy: Reliable + Value: /floorplan + Update Topic: + Depth: 5 + Durability Policy: Transient Loca + History Policy: Keep Last + Reliability Policy: Reliable + Value: /floorplan_updates + Use Timestamp: false + Value: true + Enabled: true + Global Options: + Background Color: 48; 48; 48 + Fixed Frame: map + Frame Rate: 30 + Name: root + Tools: + - Class: rviz_default_plugins/Interact + Hide Inactive Objects: true + - Class: rviz_default_plugins/MoveCamera + - Class: rviz_default_plugins/Select + - Class: rviz_default_plugins/FocusCamera + - Class: rviz_default_plugins/Measure + Line color: 128; 128; 0 + - Class: rviz_default_plugins/SetInitialPose + Covariance x: 0.25 + Covariance y: 0.25 + Covariance yaw: 0.06853891909122467 + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /initialpose + - Class: rviz_default_plugins/SetGoal + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /goal_pose + - Class: rviz_default_plugins/PublishPoint + Single click: true + Topic: + Depth: 5 + Durability Policy: Volatile + History Policy: Keep Last + Reliability Policy: Reliable + Value: /clicked_point + Transformation: + Current: + Class: rviz_default_plugins/TF + Value: true + Views: + Current: + Angle: 0.005000006407499313 + Class: rviz_default_plugins/TopDownOrtho + Enable Stereo Rendering: + Stereo Eye Separation: 0.05999999865889549 + Stereo Focal Distance: 1 + Swap Stereo Eyes: false + Value: false + Invert Z Axis: false + Name: Current View + Near Clip Distance: 0.009999999776482582 + Scale: 30.049789428710938 + Target Frame: + Value: TopDownOrtho (rviz_default_plugins) + X: 15.933613777160645 + Y: -7.778347492218018 + Saved: ~ +Window Geometry: + Displays: + collapsed: false + Height: 932 + Hide Left Dock: false + Hide Right Dock: true + NEXUSPanel: + collapsed: false + QMainWindow State: 000000ff00000000fd00000004000000000000019400000304fc020000000bfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005d00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afc0000003f000001ac000000cc00fffffffa000000010100000002fb000000120046004d004d005300500061006e0065006c0100000000ffffffff0000000000000000fb000000100044006900730070006c0061007900730100000000000001780000015600fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000c00430061006d0065007200610000000471000000e10000000000000000fb0000000a0049006d00610067006501000002e6000000950000000000000000fc000001f100000152000001120100001efa000000010100000002fb00000014004e004500580055005300500061006e0065006c010000000000000194000000e200fffffffb0000001a005300630068006500640075006c006500500061006e0065006c0100000000ffffffff0000019400ffffff000000010000012e0000033efc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000003d0000033e000000a900fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004f20000003cfc0100000002fb0000000800540069006d00650100000000000004f20000027b00fffffffb0000000800540069006d00650100000000000004500000000000000000000003580000030400000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 + SchedulePanel: + collapsed: false + Selection: + collapsed: false + Time: + collapsed: false + Tool Properties: + collapsed: false + Views: + collapsed: true + Width: 1266 + X: 1081 + Y: 67