feat(experement): add planner scene mode without reference runner
This commit is contained in:
@@ -17,7 +17,7 @@ import yaml
|
||||
|
||||
|
||||
EXPERIMENT_IDS = tuple(range(1, 21))
|
||||
MODES = ('view', 'execute')
|
||||
MODES = ('view', 'execute', 'planner')
|
||||
DEFAULT_START_DELAY_SEC = 3.0
|
||||
DEFAULT_TRACE_DIR = '~/.ros/iiwa_experement/runs'
|
||||
LOCAL_PROTOS = (
|
||||
|
||||
@@ -110,6 +110,11 @@ def supervisor_process(
|
||||
)
|
||||
|
||||
|
||||
def mode_read_only(mode: str) -> bool:
|
||||
"""Only ``view`` is passive; execute and planner accept grab commands."""
|
||||
return mode == 'view'
|
||||
|
||||
|
||||
def runtime_actions(
|
||||
experiment_id: int,
|
||||
scene_config: str,
|
||||
@@ -126,7 +131,10 @@ def runtime_actions(
|
||||
package_share = Path(get_package_share_directory('iiwa_experement'))
|
||||
if geometry_path is None:
|
||||
geometry_path = str(package_share / 'config' / 'geometry.yaml')
|
||||
read_only = mode != 'execute'
|
||||
# Only the passive view mode locks the supervisor. Both the reference
|
||||
# executor and the external-graph planner need to accept grab/dock
|
||||
# commands; the planner mode simply never starts the reference runner.
|
||||
read_only = mode_read_only(mode)
|
||||
actions = [
|
||||
IncludeLaunchDescription(
|
||||
PythonLaunchDescriptionSource(
|
||||
@@ -264,7 +272,9 @@ def generate_launch_description():
|
||||
default_value='view',
|
||||
description=(
|
||||
'view = open the prepared scene without motion; '
|
||||
'execute = run the reference sequence after start_delay_sec.'
|
||||
'execute = run the reference sequence after start_delay_sec; '
|
||||
'planner = writable scene for an externally supplied graph, '
|
||||
'no reference sequence.'
|
||||
),
|
||||
),
|
||||
DeclareLaunchArgument(
|
||||
|
||||
@@ -45,12 +45,17 @@ def test_invalid_experiment_ids_are_rejected(raw):
|
||||
validate_experiment_id(raw)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('raw, expected', [('view', 'view'), ('execute', 'execute'), (' VIEW ', 'view')])
|
||||
@pytest.mark.parametrize('raw, expected', [
|
||||
('view', 'view'),
|
||||
('execute', 'execute'),
|
||||
('planner', 'planner'),
|
||||
(' VIEW ', 'view'),
|
||||
])
|
||||
def test_valid_modes(raw, expected):
|
||||
assert validate_mode(raw) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('raw', ['', 'run', 'VIEW '[:-1] + 'x', '1'])
|
||||
@pytest.mark.parametrize('raw', ['', 'run', 'VIEW '[:-1] + 'x', '1', 'plan'])
|
||||
def test_invalid_modes_are_rejected(raw):
|
||||
with pytest.raises(ValueError):
|
||||
validate_mode(raw)
|
||||
@@ -138,6 +143,46 @@ def test_execute_adds_the_reference_runner_after_the_supervisor():
|
||||
assert any(type(action) is ExecuteProcess for action in actions)
|
||||
|
||||
|
||||
def _process_arguments(process):
|
||||
return [item[0].text for item in process.cmd if item and item[0].text]
|
||||
|
||||
|
||||
def test_planner_is_writable_and_has_no_reference_runner():
|
||||
module = load_launch_module()
|
||||
actions = module.runtime_actions(
|
||||
experiment_id=20,
|
||||
scene_config='/tmp/scenes.yaml',
|
||||
setting_path='/tmp/setting.yaml',
|
||||
mode='planner',
|
||||
)
|
||||
assert not any(
|
||||
isinstance(action, Node) and action.node_executable == 'reference_runner'
|
||||
for action in actions
|
||||
)
|
||||
processes = [action for action in actions if type(action) is ExecuteProcess]
|
||||
assert len(processes) == 1
|
||||
assert 'read_only:=false' in _process_arguments(processes[0])
|
||||
assert module.mode_read_only('planner') is False
|
||||
parameters = module.supervisor_parameters(
|
||||
20, '/tmp/scenes.yaml', '/tmp/geometry.yaml', False,
|
||||
)
|
||||
assert parameters['read_only'] is False
|
||||
|
||||
|
||||
def test_view_remains_read_only_after_adding_the_planner_mode():
|
||||
module = load_launch_module()
|
||||
actions = module.runtime_actions(
|
||||
experiment_id=1,
|
||||
scene_config='/tmp/scenes.yaml',
|
||||
setting_path='/tmp/setting.yaml',
|
||||
mode='view',
|
||||
)
|
||||
processes = [action for action in actions if type(action) is ExecuteProcess]
|
||||
assert 'read_only:=true' in _process_arguments(processes[0])
|
||||
assert module.mode_read_only('view') is True
|
||||
assert module.mode_read_only('execute') is False
|
||||
|
||||
|
||||
def test_runtime_actions_can_register_cleanup(tmp_path):
|
||||
module = load_launch_module()
|
||||
actions = module.runtime_actions(
|
||||
|
||||
@@ -14,12 +14,17 @@ from iiwa_experement.runtime_config import (
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('raw, expected', [('view', 'view'), (' Execute ', 'execute')])
|
||||
@pytest.mark.parametrize('raw, expected', [
|
||||
('view', 'view'),
|
||||
(' Execute ', 'execute'),
|
||||
('planner', 'planner'),
|
||||
(' PLANNER ', 'planner'),
|
||||
])
|
||||
def test_mode_validation(raw, expected):
|
||||
assert validate_mode(raw) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('raw', ['', 'motion', 'execute!'])
|
||||
@pytest.mark.parametrize('raw', ['', 'motion', 'execute!', 'plan'])
|
||||
def test_mode_validation_rejects_unknown_modes(raw):
|
||||
with pytest.raises(ValueError):
|
||||
validate_mode(raw)
|
||||
|
||||
Reference in New Issue
Block a user