Skip to content

Add xacro expansion service#428

Merged
iche033 merged 15 commits intointrinsic-dev:mainfrom
JenniferBuehler:feat/add-xacro-expansion-service
Apr 14, 2026
Merged

Add xacro expansion service#428
iche033 merged 15 commits intointrinsic-dev:mainfrom
JenniferBuehler:feat/add-xacro-expansion-service

Conversation

@JenniferBuehler
Copy link
Copy Markdown
Contributor

@JenniferBuehler JenniferBuehler commented Mar 16, 2026

Add an ExpandXacro ROS 2 service to the eval stack so that model-side code can request xacro-to-XML expansion without needing direct filesystem access to the eval workspace's package share directories.

Motivation:

Model policies that need to spawn or respawn entities at training time (e.g. task boards, cables) must produce SDF/URDF XML from the xacro source files in aic_description. Those xacro files and the xacro tool live inside the eval container's colcon workspace, which is not accessible from the model side. This service adds convenience here -- the model sends a package name, relative path, and xacro arguments, and gets back the expanded XML string.

Note

I am adding this PR as proposal because I think that other participants might benefit. If however it doesn't fit in the toolkit as per your design and requirements, we can just close it. Of course, this is only a feature which would make sense at training time (not at evaluation where env resets/spawning are managed by the evaluation).

Test plan

Build and start the eval environment

cd aic
# Rebuild docker, e.g. with
docker buildx build --load -t aic_eval:local -f docker/aic_eval/Dockerfile .
# Recreate the distrobox container from the new image:
distrobox rm aic_eval  # if it already exists
distrobox create -r --nvidia -i aic_eval:local aic_eval

Start the eval environment - there is now an entrypoint that starts up the same as /entrypoint.sh but instead uses the wrapper launch file which also brings up the xacro expander service node:

  distrobox enter aic_eval -- /entrypoint_training.sh \
    spawn_task_board:=true \
    nic_card_mount_2_present:=true \
    spawn_cable:=true \
    cable_type:=sfp_sc_cable \
    ground_truth:=true \
    start_aic_engine:=false

Verify the service is advertised

In a second terminal (host side, pixi workspace):

pixi run ros2 service list | grep expand_xacro

Expected output:

/expand_xacro

Call the service with a valid xacro file

Expand the task board xacro with a minimal set of arguments:

  pixi run ros2 service call /expand_xacro aic_training_interfaces/srv/ExpandXacro \
    "{package_name: 'aic_description', relative_path: 'urdf/task_board.urdf.xacro', xacro_arguments:
  ['ground_truth:=true', 'nic_card_mount_0_present:=true', 'nic_card_mount_0_translation:=0.0']}"

Expected: success: true, xml contains a non-empty SDF/URDF string, message is "xacro expansion succeeded".

Call the service with an invalid package name

pixi run ros2 service call /expand_xacro aic_training_interfaces/srv/ExpandXacro \
  "{package_name: 'nonexistent_package', relative_path: 'foo.xacro', xacro_arguments: []}"

Expected: success: false, message mentions the package was not found.

Call the service with a path traversal attempt

pixi run ros2 service call /expand_xacro aic_training_interfaces/srv/ExpandXacro \
  "{package_name: 'aic_description', relative_path: '../../etc/passwd', xacro_arguments: []}"

Expected: success: false, message is
"relative_path must stay within the package share directory".

Verify no regressions in the standard bringup

Start the eval environment with the engine enabled and confirm the existing evaluation flow still works:

distrobox enter aic_eval -- /entrypoint.sh \
  ground_truth:=false \
  start_aic_engine:=true

Verify that the engine runs its trials normally and the xacro_expander node does not interfere (check ros2 node list includes /xacro_expander; no errors in the bringup output).

Comment thread aic_utils/aic_training_interfaces/pixi.toml
Comment thread pixi.toml
Comment thread docker/aic_eval/Dockerfile Outdated
@JenniferBuehler JenniferBuehler marked this pull request as ready for review March 16, 2026 22:22
@Yadunund Yadunund added the enhancement New feature or request label Mar 17, 2026
Copy link
Copy Markdown
Collaborator

@Yadunund Yadunund left a comment

Choose a reason for hiding this comment

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

@JenniferBuehler, thanks for the PR! This is a great addition to the toolkit and will be incredibly helpful for participants spawning entities during training.

Since these changes currently affect several core packages used in evaluation, I’d like to propose a refactor to ensure we don't introduce any regressions to the eval environment. By isolating these features, we can keep the core stable while still providing these tools to the community.

Proposed Changes:

  • Create aic_training_utils package: Let’s house this in aic_utils with dedicated launch and scripts directories.

  • New Launch Logic: Create a launch file in the new package that includes the existing aic_bringup/aic_gz_bringup.launch.py and also starts the xacro_expander node.

  • Dedicated Interfaces: Create an aic_training_interfaces package within aic_utils to host the ExpandXacro.srv.

This approach keeps the evaluation environment clean while making your training improvements easily accessible to everyone.

Let me know what you think!

Comment thread docker/aic_eval/Dockerfile Outdated
@JenniferBuehler
Copy link
Copy Markdown
Contributor Author

@JenniferBuehler, thanks for the PR! This is a great addition to the toolkit and will be incredibly helpful for participants spawning entities during training.

Since these changes currently affect several core packages used in evaluation, I’d like to propose a refactor to ensure we don't introduce any regressions to the eval environment. By isolating these features, we can keep the core stable while still providing these tools to the community.

Proposed Changes:

  • Create aic_training_utils package: Let’s house this in aic_utils with dedicated launch and scripts directories.
  • New Launch Logic: Create a launch file in the new package that includes the existing aic_bringup/aic_gz_bringup.launch.py and also starts the xacro_expander node.
  • Dedicated Interfaces: Create an aic_training_interfaces package within aic_utils to host the ExpandXacro.srv.

This approach keeps the evaluation environment clean while making your training improvements easily accessible to everyone.

Let me know what you think!

Thanks @Yadunund this is a really great suggestion! I have applied the requested changes. I took the liberty to also add a convenience entrypoint, so the training-version of the eval env (which brings up the xacro expander node) can be brought up easily. I also updated the test plan accordingly.

@JenniferBuehler
Copy link
Copy Markdown
Contributor Author

JenniferBuehler commented Mar 21, 2026

@Yadunund can you please help me out with the guidelines you have for the pixi.lock file? I have added my re-generated version for now.

Comment thread aic_utils/aic_training_utils/package.xml
@JenniferBuehler JenniferBuehler requested a review from Yadunund April 3, 2026 22:06
Comment thread docker/aic_eval/Dockerfile Outdated
@iche033
Copy link
Copy Markdown
Collaborator

iche033 commented Apr 6, 2026

This looks great!

@Yadunund can you please help me out with the guidelines you have for the pixi.lock file? I have added my re-generated version for now.

Is it possible to make minimal changes to the pixi.lock file without updating other dependencies? e.g. I reverted pixi.lock and manually ran pixi install to add only the aic_utils/aic_training_interfaces entry.

@JenniferBuehler
Copy link
Copy Markdown
Contributor Author

This looks great!

@Yadunund can you please help me out with the guidelines you have for the pixi.lock file? I have added my re-generated version for now.

Is it possible to make minimal changes to the pixi.lock file without updating other dependencies? e.g. I reverted pixi.lock and manually ran pixi install to add only the aic_utils/aic_training_interfaces entry.

Just did that, thanks for the tip! I'm still learning pixi :)

@iche033 iche033 merged commit d302953 into intrinsic-dev:main Apr 14, 2026
4 checks passed
rishimalhan pushed a commit to ensembl-ai/aic that referenced this pull request Apr 18, 2026
Add an ExpandXacro ROS 2 service to the eval stack so that model-side code can request xacro-to-XML expansion without needing direct filesystem access to the eval workspace's package share directories.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants