Skip to content

[PARSER] Replace goal-state configuration with meta-profile format - #1

Open
lakhmanisahil wants to merge 10 commits into
feat/meta-profiles-and-inferencefrom
feat/add-new-meta-profiles-format
Open

[PARSER] Replace goal-state configuration with meta-profile format#1
lakhmanisahil wants to merge 10 commits into
feat/meta-profiles-and-inferencefrom
feat/add-new-meta-profiles-format

Conversation

@lakhmanisahil

@lakhmanisahil lakhmanisahil commented Jun 29, 2026

Copy link
Copy Markdown
Owner

Description

This PR replaces the existing goal_states configuration with the new profiles and meta_profiles format.

To preserve the existing Foreman engine, the parser expands each meta-profile into a SystemGoal during parsing. As a result, the planner and engine continue to operate on SystemGoals without requiring any changes.

This PR is stacked on top of feat/meta-profiles-and-inference.{PR #16: dependency inference}


Changes

Configuration format

  • Replace goal_states with profiles and meta_profiles
  • Migrate the example scenario to the new configuration format
  • Support reusable profiles containing:
    • controllers
    • hardware
    • lifecycle nodes
  • Support meta-profiles that assign target lifecycle states to profiles

Parser

  • Parse the new profiles section
  • Parse the new meta_profiles section
  • Expand each meta-profile into a SystemGoal
  • Derive hardware and lifecycle node lists from the referenced profiles
  • Preserve the existing ParsedScenario interface for the engine
  • Keep dependency rules inferred at runtime

Validation

Added parser validation for:

  • unknown profile references
  • missing profile state declarations

Tests

  • Update parser tests for the new configuration format
  • Add parser validation tests
  • Verify generated SystemGoals from meta-profiles

Testing

Environment

  • ROS 2 Lyrical/Jazzy
  • ros2_control_demos Example 1 (RRBot)

Build

cd ~/my_ws

colcon build --symlink-install

source install/setup.bash

Unit Tests

Successfully executed:

pytest src/foreman/foreman/test/test_parser.py

colcon build --packages-select foreman

colcon test --packages-select foreman

colcon test-result --verbose

All tests passed successfully.


Manual Validation

Validated using ros2_control_demo_example_1.

Terminal 1

ros2 run foreman dummy_lifecycle_node

Terminal 2

ros2 launch ros2_control_demo_example_1 rrbot.launch.py

Terminal 3

ros2 run foreman foreman_node --ros-args \
  -p config_path:=<path-to-yaml>

Terminal 4

Switch between meta-profiles:

ros2 service call /foreman/set_goal foreman_msgs/srv/SetGoal "{goal: 'full_active'}"

ros2 service call /foreman/set_goal foreman_msgs/srv/SetGoal "{goal: 'all_down'}"

ros2 service call /foreman/set_goal foreman_msgs/srv/SetGoal "{goal: 'sensing_only'}"

Here SetGoal refers to a meta-profile.

Foreman successfully expanded the selected meta-profile into the corresponding SystemGoal and executed the requested transitions.


YAML used for testing

profiles:
  motion:
    controllers:
      - forward_position_controller

  sensing:
    controllers:
      - joint_state_broadcaster
    hardware:
      - RRBot
    lifecycle_nodes:
      - dummy_lifecycle_node

meta_profiles:
  full_active:
    motion: {state: active}
    sensing: {state: active}

  sensing_only:
    motion: {state: inactive}
    sensing: {state: active}

  all_down:
    motion: {state: inactive}
    sensing: {state: inactive}

Is this a user-facing behavior change?

Yes.

The scenario configuration format changes from goal_states to profiles and meta_profiles.

Existing configuration files using goal_states must be migrated to the new format.

The public SetGoal API remains unchanged; users now specify the name of a meta-profile instead of a goal state.


Did you use Generative AI?

Yes (OpenAI GPT-5.5) was used for assistance.


Additional Information

Testing with example_1

image

Add initial support for parsing the meta-profile configuration format.

Each meta-profile is parsed into a SystemGoal by name.
Expand controllers, hardware and lifecycle nodes referenced by a profile into the corresponding SystemGoal.

Each component inherits the lifecycle state specified by the enclosing profile_name_ under meta-profile_name.

Signed-off-by: root <lakhmanisahil8@gmail.com>
This removes the need for top-level hardware and lifecycle node lists
when parsing the meta-profile configuration format.

Signed-off-by: root <lakhmanisahil8@gmail.com>
Populate the tracked component list from the parsed goals.

Reuse the existing tracked-component derivation logic so the
meta-profile parser produces the same tracked component set as the
old goal-state parser.

Signed-off-by: root <lakhmanisahil8@gmail.com>
Signed-off-by: root <lakhmanisahil8@gmail.com>
Require every profile referenced by a meta-profile to declare a
lifecycle state.

Signed-off-by: root <lakhmanisahil8@gmail.com>
Replace the ols goal-state configuration with the new
profile & meta-profile schema.

This preserves the existing parsed scenario while migrating the
configuration to the new format.

Signed-off-by: ...Signed-off-by: root <lakhmanisahil8@gmail.com>
Update the parser test file to use the meta-profile format and
include validation tests for the new configuration format.

Signed-off-by: root <lakhmanisahil8@gmail.com>
Signed-off-by: root <lakhmanisahil8@gmail.com>
Signed-off-by: root <lakhmanisahil8@gmail.com>
Comment on lines +107 to +138
def test_missing_profile_reference_raises(self, tmp_path):
config = tmp_path / "missing_profile.yaml"

config.write_text(
"profiles:\n"
" motion:\n"
" controllers: [controller]\n"
"\n"
"meta_profiles:\n"
" running:\n"
" missing_profile:\n"
" state: active\n"
)

with pytest.raises(ValueError):
parse_yaml_file(config)

def test_missing_profile_state_raises(self, tmp_path):
config = tmp_path / "missing_state.yaml"

config.write_text(
"profiles:\n"
" motion:\n"
" controllers: [controller]\n"
"\n"
"meta_profiles:\n"
" running:\n"
" motion: {}\n"
)

with pytest.raises(ValueError):
parse_yaml_file(config)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about testing valid cases?. Is it already handled in previous tests?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the valid cases are already covered 👍

@lakhmanisahil
lakhmanisahil marked this pull request as ready for review July 1, 2026 23:34
@lakhmanisahil lakhmanisahil changed the title Replace goal-state configuration with meta-profile format [PARSER] Replace goal-state configuration with meta-profile format Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants