Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
50 changes: 50 additions & 0 deletions code/SIMULATION_SMALL_HOUSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Manipulator in `small_house` Gazebo world

This workspace now contains two pieces wired together:

- `small_house`: a small ROS 2 resource package that installs the Gazebo world and all `model://...` assets.
- `manipulator_description`: the robot description and launch files that spawn the manipulator into that world.

## Build

From the workspace root:

```bash
colcon build --packages-select small_house manipulator_description --symlink-install
source install/setup.bash
```

If dependencies such as `ur_description`, `ur_simulation_gz`, `ros_gz_sim`, `gz_ros2_control`, `mia_hand_description`, or `controller_manager` are missing, install/source those first or build the complete workspace:

```bash
colcon build --symlink-install
source install/setup.bash
```

## Start Gazebo with apartment + manipulator

```bash
ros2 launch manipulator_description manipulator.house.sim.launch.py
```

Useful arguments:

```bash
ros2 launch manipulator_description manipulator.house.sim.launch.py ur_type:=ur5e launch_rviz:=true
ros2 launch manipulator_description manipulator.house.sim.launch.py ur_type:=ur10e
ros2 launch manipulator_description manipulator.house.sim.launch.py gazebo_gui:=false
```

## Start full stack with MoveIt/RViz

```bash
ros2 launch manipulator_description manipulator.house.full.sim.launch.py
```

## What changed

1. `small_house` was converted into an installable ROS 2 package by adding `package.xml` and `CMakeLists.txt`.
2. `small_house/worlds/small_house.world` was added as installed world path.
3. The old TurtleBot include was removed from the world, because the manipulator launch spawns the robot instead.
4. `manipulator.house.sim.launch.py` sets `GZ_SIM_RESOURCE_PATH` and `IGN_GAZEBO_RESOURCE_PATH` so Gazebo can resolve all `model://aws_...` assets.
5. `manipulator.full.sim.launch.py` now forwards `world_file` and `gazebo_gui` to the lower Gazebo launch.
244 changes: 244 additions & 0 deletions code/arlab_movement/launch/ranger_nav2.launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
"""Minimal Nav2 launch for the simulated Ranger Air mobile manipulator.

It expects:
- /odom and odom -> ranger_base_link from Gazebo OdometryPublisher
- /scan from the simulated lidar
- map -> odom from SLAM Toolbox or AMCL
- /cmd_vel is bridged to Gazebo
"""

import os

from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, GroupAction, SetEnvironmentVariable
from launch.conditions import IfCondition
from launch.substitutions import LaunchConfiguration, PythonExpression
from launch_ros.actions import LoadComposableNodes, Node, PushROSNamespace, SetParameter
from launch_ros.descriptions import ComposableNode, ParameterFile
from nav2_common.launch import RewrittenYaml


def generate_launch_description():
bringup_dir = get_package_share_directory("arlab_movement")

namespace = LaunchConfiguration("namespace")
use_sim_time = LaunchConfiguration("use_sim_time")
autostart = LaunchConfiguration("autostart")
params_file = LaunchConfiguration("params_file")
use_composition = LaunchConfiguration("use_composition")
container_name = LaunchConfiguration("container_name")
container_name_full = (namespace, "/", container_name)
use_respawn = LaunchConfiguration("use_respawn")
log_level = LaunchConfiguration("log_level")

lifecycle_nodes = [
"controller_server",
"smoother_server",
"planner_server",
"behavior_server",
"velocity_smoother",
"bt_navigator",
"waypoint_follower",
]

remappings = [("/tf", "tf"), ("/tf_static", "tf_static")]
configured_params = ParameterFile(
RewrittenYaml(
source_file=params_file,
root_key=namespace,
param_rewrites={"autostart": autostart},
convert_types=True,
),
allow_substs=True,
)

stdout_linebuf_envvar = SetEnvironmentVariable("RCUTILS_LOGGING_BUFFERED_STREAM", "1")

declare_namespace_cmd = DeclareLaunchArgument("namespace", default_value="", description="Top-level namespace")
declare_use_sim_time_cmd = DeclareLaunchArgument("use_sim_time", default_value="true", description="Use Gazebo sim time")
declare_params_file_cmd = DeclareLaunchArgument(
"params_file",
default_value=os.path.join(bringup_dir, "params", "ranger_nav2_params.yaml"),
description="Full path to the Nav2 parameters file",
)
declare_autostart_cmd = DeclareLaunchArgument("autostart", default_value="true", description="Autostart Nav2")
declare_use_composition_cmd = DeclareLaunchArgument("use_composition", default_value="False")
declare_container_name_cmd = DeclareLaunchArgument("container_name", default_value="nav2_container")
declare_use_respawn_cmd = DeclareLaunchArgument("use_respawn", default_value="False")
declare_log_level_cmd = DeclareLaunchArgument("log_level", default_value="info")

load_nodes = GroupAction(
condition=IfCondition(PythonExpression(["not ", use_composition])),
actions=[
PushROSNamespace(namespace),
SetParameter("use_sim_time", use_sim_time),
Node(
package="nav2_controller",
executable="controller_server",
name="controller_server",
output="screen",
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=["--ros-args", "--log-level", log_level],
remappings=remappings + [("cmd_vel", "cmd_vel_nav")],
),
Node(
package="nav2_smoother",
executable="smoother_server",
name="smoother_server",
output="screen",
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=["--ros-args", "--log-level", log_level],
remappings=remappings,
),
Node(
package="nav2_planner",
executable="planner_server",
name="planner_server",
output="screen",
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=["--ros-args", "--log-level", log_level],
remappings=remappings,
),
Node(
package="nav2_behaviors",
executable="behavior_server",
name="behavior_server",
output="screen",
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=["--ros-args", "--log-level", log_level],
remappings=remappings + [("cmd_vel", "cmd_vel_nav")],
),
Node(
package="nav2_bt_navigator",
executable="bt_navigator",
name="bt_navigator",
output="screen",
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=["--ros-args", "--log-level", log_level],
remappings=remappings,
),
Node(
package="nav2_waypoint_follower",
executable="waypoint_follower",
name="waypoint_follower",
output="screen",
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=["--ros-args", "--log-level", log_level],
remappings=remappings,
),
Node(
package="nav2_velocity_smoother",
executable="velocity_smoother",
name="velocity_smoother",
output="screen",
respawn=use_respawn,
respawn_delay=2.0,
parameters=[configured_params],
arguments=["--ros-args", "--log-level", log_level],
remappings=remappings + [("cmd_vel", "cmd_vel_nav"), ("cmd_vel_smoothed", "cmd_vel")],
),
Node(
package="nav2_lifecycle_manager",
executable="lifecycle_manager",
name="lifecycle_manager_navigation",
output="screen",
arguments=["--ros-args", "--log-level", log_level],
parameters=[{"use_sim_time": use_sim_time}, {"autostart": autostart}, {"node_names": lifecycle_nodes}],
),
],
)

load_composable_nodes = GroupAction(
condition=IfCondition(use_composition),
actions=[
PushROSNamespace(namespace),
SetParameter("use_sim_time", use_sim_time),
LoadComposableNodes(
target_container=container_name_full,
composable_node_descriptions=[
ComposableNode(
package="nav2_controller",
plugin="nav2_controller::ControllerServer",
name="controller_server",
parameters=[configured_params],
remappings=remappings + [("cmd_vel", "cmd_vel_nav")],
),
ComposableNode(
package="nav2_smoother",
plugin="nav2_smoother::SmootherServer",
name="smoother_server",
parameters=[configured_params],
remappings=remappings,
),
ComposableNode(
package="nav2_planner",
plugin="nav2_planner::PlannerServer",
name="planner_server",
parameters=[configured_params],
remappings=remappings,
),
ComposableNode(
package="nav2_behaviors",
plugin="behavior_server::BehaviorServer",
name="behavior_server",
parameters=[configured_params],
remappings=remappings + [("cmd_vel", "cmd_vel_nav")],
),
ComposableNode(
package="nav2_bt_navigator",
plugin="nav2_bt_navigator::BtNavigator",
name="bt_navigator",
parameters=[configured_params],
remappings=remappings,
),
ComposableNode(
package="nav2_waypoint_follower",
plugin="nav2_waypoint_follower::WaypointFollower",
name="waypoint_follower",
parameters=[configured_params],
remappings=remappings,
),
ComposableNode(
package="nav2_velocity_smoother",
plugin="nav2_velocity_smoother::VelocitySmoother",
name="velocity_smoother",
parameters=[configured_params],
remappings=remappings + [("cmd_vel", "cmd_vel_nav"), ("cmd_vel_smoothed", "cmd_vel")],
),
ComposableNode(
package="nav2_lifecycle_manager",
plugin="nav2_lifecycle_manager::LifecycleManager",
name="lifecycle_manager_navigation",
parameters=[{"use_sim_time": use_sim_time, "autostart": autostart, "node_names": lifecycle_nodes}],
),
],
),
],
)

ld = LaunchDescription()
ld.add_action(stdout_linebuf_envvar)
ld.add_action(declare_namespace_cmd)
ld.add_action(declare_use_sim_time_cmd)
ld.add_action(declare_params_file_cmd)
ld.add_action(declare_autostart_cmd)
ld.add_action(declare_use_composition_cmd)
ld.add_action(declare_container_name_cmd)
ld.add_action(declare_use_respawn_cmd)
ld.add_action(declare_log_level_cmd)
ld.add_action(load_nodes)
ld.add_action(load_composable_nodes)
return ld
Loading
Loading