launch icon indicating copy to clipboard operation
launch copied to clipboard

Setting additional_env in a ComposableNodeContainer will set the launch's environment as well

Open omertal88 opened this issue 1 year ago • 2 comments

Bug report

Required Info:

  • Operating System:
    • Ubuntu 22.04
  • Installation type:
    • Binaries
  • Version or commit hash:
    • humble
  • DDS implementation:
    • CycloneDDS
  • Client library (if applicable):
    • rclcpp

Steps to reproduce issue

  1. Create 2 CycloneDDS profiles where each has its own unique participant ID.
  2. Set environment variable for CYCLONEDDS_URI=file://<profile-path>.
  3. Create a launch file which runs a ComposableNodeContainer with some components (as seem in this example
  4. **If you try to run this now, it will fail because both the ComposableNodeContainer and the ROS2 temporary node which is used to load components are trying to use the same ports. **
  5. Set additional_env e.g.: {"CYCLONEDDS_URI": "file://<path-to-other-profile>}
  6. Run the launch file.

Expected behavior

The composable node container should match the ports of the second profile (step 5), while the ROS2 node which send the LoadNode requests use the ports matching the ports of the first profile (step 2).

Actual behavior

You will get the same error as in step 4, but this time the ports match the ports of the second profile. This actually means that you can't run a composable node container with pre-defined participant ID.

Additional information

This worked fine in galactic, and when we try to port to humble, we stumbled upon this issue

Thank you Omer

omertal88 avatar Jun 29 '23 14:06 omertal88

Hey there! Could you upload a minimal example so we can look into this issue?

Edit: Note-to-self: It could be that this line is shallow copying the env dict.

methylDragon avatar Jul 06 '23 17:07 methylDragon

I actually just ran into this, but the problem seems a little more subtle... Please use the following to reproduce.

First a simple executable:

#!/usr/bin/env python3
import os

print(os.environ.get("FOO", "There is no foo"))

Place it somewhere on your path, I named it print_env.py.

Then the following launch file:

import launch


def generate_launch_description():
    ld = launch.LaunchDescription()

    ld.add_action(
        launch.actions.ExecuteProcess(
            cmd=["print_env.py"], additional_env={"FOO": "BAR"}, output="screen"
        )
    )

    ld.add_action(launch.actions.ExecuteProcess(cmd=["print_env.py"], output="screen"))

    ld.add_action(
        launch.actions.ExecuteProcess(
            cmd=["print_env.py"],
            output="screen",
            additional_env={
                "FOO": launch.substitutions.Command(
                    [
                        "print_env.py",
                    ]
                )
            },
        )
    )

    return ld

This launches three "printenv" processes:

  • The first one has additional_env set to FOO=BAR
  • The second one has nothing set
  • The third one sets the FOO value to the contents of the environment variable, using a substitutions.Command

So I expect:

  • BAR
  • There is no foo
  • There is no foo

What I get:

  • BAR
  • There is no foo
  • BAR !

So it seems that additional_env leaks into the command substitution, but maybe not to other nodes / processes? Note that this is not exactly the same behaviour as exposed above, but maybe my MWE will help in resolving this?

haudren-woven avatar Nov 02 '23 05:11 haudren-woven