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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
API changes in MoveIt releases

## ROS Rolling
- [07/2026] Generated warehouse launch files now use SQLite instead of MongoDB. Use `moveit_warehouse_database_path` to select the SQLite database file. The MongoDB-specific `moveit_warehouse_host` and `moveit_warehouse_port` launch arguments were removed. By default, the database is created in `$ROS_HOME` (or `~/.ros`) with a config-package-specific filename.
- [11/2024] All MoveIt 2 headers have been updated to use the .hpp extension. .h headers are now autogenerated with a deprecation warning, and may be removed in future releases. Please update your imports to use the .hpp headers.
- [11/2024] Added flags to control padding to CollisionRequest. This change deprecates PlanningScene::checkCollisionUnpadded(..) functions. Please use PlanningScene::checkCollision(..) with a req.pad_environment_collisions = false;

Expand Down
95 changes: 40 additions & 55 deletions moveit_configs_utils/moveit_configs_utils/launches.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
from launch import LaunchDescription
from launch.actions import (
DeclareLaunchArgument,
GroupAction,
IncludeLaunchDescription,
)
from launch.conditions import IfCondition
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import LaunchConfiguration

from launch_ros.actions import Node
from launch_ros.actions import Node, SetParameter
from launch_ros.parameter_descriptions import ParameterValue

from srdfdom.srdf import SRDF
Expand Down Expand Up @@ -134,52 +135,38 @@ def generate_spawn_controllers_launch(moveit_config):


def generate_warehouse_db_launch(moveit_config):
"""Launch file for warehouse database"""
"""Launch file for SQLite warehouse database."""
ld = LaunchDescription()
ld.add_action(
DeclareLaunchArgument(
"moveit_warehouse_database_path",
default_value=str(
moveit_config.package_path / "default_warehouse_mongo_db"
default_value=os.path.join(
os.environ.get("ROS_HOME", os.path.expanduser("~/.ros")),
f"{moveit_config.package_path.name}_warehouse.sqlite",
),
)
)
ld.add_action(DeclareBooleanLaunchArg("reset", default_value=False))

# The default DB port for moveit (not default MongoDB port to avoid potential conflicts)
ld.add_action(DeclareLaunchArgument("moveit_warehouse_port", default_value="33829"))

# The default DB host for moveit
ld.add_action(
DeclareLaunchArgument("moveit_warehouse_host", default_value="localhost")
SetParameter(
name="warehouse_plugin",
value="warehouse_ros_sqlite::DatabaseConnection",
)
)

# Load warehouse parameters
db_parameters = [
{
"overwrite": False,
"database_path": LaunchConfiguration("moveit_warehouse_database_path"),
"warehouse_port": LaunchConfiguration("moveit_warehouse_port"),
"warehouse_host": LaunchConfiguration("moveit_warehouse_host"),
"warehouse_exec": "mongod",
"warehouse_plugin": "warehouse_ros_mongo::MongoDatabaseConnection",
},
]
# Run the DB server
db_node = Node(
package="warehouse_ros_mongo",
executable="mongo_wrapper_ros.py",
# TODO(dlu): Figure out if this needs to be run in a specific directory
# (ROS 1 version set cwd="ROS_HOME")
parameters=db_parameters,
ld.add_action(
SetParameter(
name="warehouse_host",
value=LaunchConfiguration("moveit_warehouse_database_path"),
)
)
ld.add_action(db_node)

# If we want to reset the database, run this node
# If requested, reset the database and add the default scene and robot state.
reset_node = Node(
package="moveit_ros_warehouse",
executable="moveit_init_demo_warehouse",
output="screen",
parameters=[moveit_config.to_dict()],
condition=IfCondition(LaunchConfiguration("reset")),
)
ld.add_action(reset_node)
Expand Down Expand Up @@ -277,7 +264,7 @@ def generate_demo_launch(moveit_config, launch_package_path=None):
DeclareBooleanLaunchArg(
"db",
default_value=False,
description="By default, we do not start a database (it can be large)",
description="By default, we do not configure a warehouse database",
)
)
ld.add_action(
Expand Down Expand Up @@ -309,31 +296,29 @@ def generate_demo_launch(moveit_config, launch_package_path=None):
)
)

# Limit warehouse parameters to the nodes that consume them.
ld.add_action(
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
str(launch_package_path / "launch/move_group.launch.py")
),
)
)

# Run Rviz and load the default config to see the state of the move_group node
ld.add_action(
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
str(launch_package_path / "launch/moveit_rviz.launch.py")
),
condition=IfCondition(LaunchConfiguration("use_rviz")),
)
)

# If database loading was enabled, start mongodb as well
ld.add_action(
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
str(launch_package_path / "launch/warehouse_db.launch.py")
),
condition=IfCondition(LaunchConfiguration("db")),
GroupAction(
actions=[
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
str(launch_package_path / "launch/warehouse_db.launch.py")
),
condition=IfCondition(LaunchConfiguration("db")),
),
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
str(launch_package_path / "launch/move_group.launch.py")
),
),
# Run Rviz and load the default MoveIt configuration.
IncludeLaunchDescription(
PythonLaunchDescriptionSource(
str(launch_package_path / "launch/moveit_rviz.launch.py")
),
condition=IfCondition(LaunchConfiguration("use_rviz")),
),
]
)
)

Expand Down
148 changes: 148 additions & 0 deletions moveit_configs_utils/test/test_warehouse_launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
from pathlib import Path
from types import SimpleNamespace

from launch import LaunchContext
from launch.actions import (
DeclareLaunchArgument,
GroupAction,
IncludeLaunchDescription,
LogInfo,
)
from launch.conditions import IfCondition
from launch_ros.actions import SetParameter

from moveit_configs_utils import launches


def _execute_parameter_actions(actions, context):
for action in actions:
if isinstance(action, (DeclareLaunchArgument, SetParameter)):
action.execute(context)


def test_generate_warehouse_db_launch_uses_sqlite(monkeypatch, tmp_path):
node_calls = []
ros_home = tmp_path / "ros_home"
config_package_path = tmp_path / "test_moveit_config"
monkeypatch.setenv("ROS_HOME", str(ros_home))

def capture_node(**kwargs):
node_calls.append(kwargs)
return LogInfo(msg="captured node")

monkeypatch.setattr(launches, "Node", capture_node)

moveit_parameters = {
"robot_description": "<robot name='test'/>",
"robot_description_semantic": "<robot name='test'/>",
}
moveit_config = SimpleNamespace(
package_path=config_package_path,
to_dict=lambda: moveit_parameters,
)

launch_description = launches.generate_warehouse_db_launch(moveit_config)
actions = launch_description.entities

launch_arguments = {
action.name: action
for action in actions
if isinstance(action, DeclareLaunchArgument)
}
assert set(launch_arguments) == {
"moveit_warehouse_database_path",
"reset",
}

set_parameters = [action for action in actions if isinstance(action, SetParameter)]
assert len(set_parameters) == 2

context = LaunchContext()
_execute_parameter_actions(actions, context)

assert context.launch_configurations["moveit_warehouse_database_path"] == str(
ros_home / "test_moveit_config_warehouse.sqlite"
)

global_parameters = dict(context.launch_configurations["global_params"])
assert global_parameters == {
"warehouse_plugin": "warehouse_ros_sqlite::DatabaseConnection",
"warehouse_host": str(ros_home / "test_moveit_config_warehouse.sqlite"),
}

custom_database_path = str(tmp_path / "custom.sqlite")
custom_context = LaunchContext()
custom_context.launch_configurations["moveit_warehouse_database_path"] = (
custom_database_path
)
_execute_parameter_actions(actions, custom_context)

custom_parameters = dict(custom_context.launch_configurations["global_params"])
assert custom_parameters["warehouse_host"] == custom_database_path

# SQLite requires no separate server, so only the reset node is generated.
assert len(node_calls) == 1

reset_node = node_calls[0]
assert reset_node["package"] == "moveit_ros_warehouse"
assert reset_node["executable"] == "moveit_init_demo_warehouse"
assert reset_node["output"] == "screen"
assert reset_node["parameters"] == [moveit_parameters]
assert isinstance(reset_node["condition"], IfCondition)

context.launch_configurations["reset"] = "true"
assert reset_node["condition"].evaluate(context)

context.launch_configurations["reset"] = "false"
assert not reset_node["condition"].evaluate(context)


def test_demo_launch_scopes_warehouse_before_consumers(tmp_path):
launch_directory = tmp_path / "launch"
launch_directory.mkdir()

launch_file_contents = """\
from launch import LaunchDescription


def generate_launch_description():
return LaunchDescription()
"""

for filename in (
"rsp.launch.py",
"warehouse_db.launch.py",
"move_group.launch.py",
"moveit_rviz.launch.py",
"spawn_controllers.launch.py",
):
(launch_directory / filename).write_text(launch_file_contents)

moveit_config = SimpleNamespace(package_path=tmp_path)
launch_description = launches.generate_demo_launch(moveit_config)

groups = [
action
for action in launch_description.entities
if isinstance(action, GroupAction)
]
assert len(groups) == 1

includes = [
action
for action in groups[0].get_sub_entities()
if isinstance(action, IncludeLaunchDescription)
]

context = LaunchContext()
include_names = []
for action in includes:
source = action.launch_description_source
source.get_launch_description(context)
include_names.append(Path(source.location).name)

assert include_names == [
"warehouse_db.launch.py",
"move_group.launch.py",
"moveit_rviz.launch.py",
]