0
$\begingroup$

Rosanswers logo

I use ROS2 Galactic and have a package that spawn a URDF robot model in Gazebo. The problem is that the URDF model uses meshes files and Gazebo is not able to find them if I don't append the package install path to GAZEBO_MODEL_PATH. Using the following line the model load without problem:

export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:/home/ros/Documents/ROS2/ros2_ws/install/mars_robot/share/mars_robot

But I am wondering if it is possible to set that environment variable inside a launch file. I have tried with the following code but it doesn't work.

import os
import xacro

from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription 
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Node
from launch.actions import SetEnvironmentVariable

def generate_launch_description():

    gazebo = IncludeLaunchDescription(
                PythonLaunchDescriptionSource([os.path.join(
                    get_package_share_directory('gazebo_ros'), 'launch'), '/gazebo.launch.py']),
             )

    xacro_robot_pkg_path = os.path.join(
        get_package_share_directory('mars_robot'))

    xacro_file = os.path.join(xacro_robot_pkg_path,
                              'urdf',
                              'mars_robot.xacro')

    doc = xacro.parse(open(xacro_file))
    xacro.process_doc(doc)
    params = {'robot_description': doc.toxml()}

    node_robot_state_publisher = Node(
        package='robot_state_publisher',
        executable='robot_state_publisher',
        output='screen',
        parameters=[params]
    )

    spawn_entity = Node(package='gazebo_ros', executable='spawn_entity.py',
                        arguments=['-topic', 'robot_description',
                                   '-entity', 'mars_robot'],
                        output='screen')

    return launch.LaunchDescription([
        SetEnvironmentVariable(name='GAZEBO_MODEL_PATH', value='/home/ros/Documents/ROS2/ros2_ws/install/mars_robot/share/mars_robot'),
        gazebo,
        node_robot_state_publisher,
        spawn_entity,
    ])

Am I doing something wrong or symply it is not possible what i am trying?

Thanks for your help and best regards.


Originally posted by joseecm on ROS Answers with karma: 130 on 2022-02-27

Post score: 0

$\endgroup$

3 Answers 3

0
$\begingroup$

Rosanswers logo

I think you are seeking this functionality:

https://docs.ros.org/en/galactic/How-To-Guides/Launch-files-migration-guide.html#new-tags-in-ros-2

This issue has some examples for using set_env in XML or from launch.actions import SetEnvironmentVariable in Python.


Originally posted by ljaniec with karma: 3064 on 2022-02-27

This answer was ACCEPTED on the original site

Post score: 0


Original comments

Comment by joseecm on 2022-03-01:
Thanks for your answer. I have seen the examples and I don't see any difference between them and the use of SetEnvironmentVariable in my code. But the fact is:

This works: export GAZEBO_MODEL_PATH=/home/ros/Documents/ROS2/ros2_ws/install/mars_robot/share/mars_robot

This doesn't work: SetEnvironmentVariable(name='GAZEBO_MODEL_PATH', value='/home/ros/Documents/ROS2/ros2_ws/install/mars_robot/share/mars_robot'),

Any idea what could be the reason?

Best regards.

Comment by ljaniec on 2022-03-01:
I can see the difference in your return value with LaunchDescription instead of launch.LaunchDescription. It shouldn't matter, though. Maybe try the version with GroupAction too? Is the part with env_value correct for sure? You can try to use SetEnvironmentVariable with some dummy variable with hard-coded value just to see if it's working. Then try to modify the GAZEBO_MODEL_PATH with your path as string - if it works, try to use your env_value too. In the end, you should try @Fetullah Atas version in his answer too.

Comment by joseecm on 2022-03-01:
I have edited mi original post to simplify the code. As you can see I have hardcoded the path I want to set in GAZEBO_MODEL_PATH, using the same I use with export. The code doesn't work. When I run the launch file Gazebo keeps loading for little more than a minute and at the end links with references to meshes files doesn't appear. I have also try the version with GroupAction and what propose @Fetullah Atas in his answer, but with the same result. I really don't know what is happening.

Comment by ljaniec on 2022-03-01:
Can you add --verbose to the Gazebo launch parameters? Just to see what kind of problems Gazebo have with this

$\endgroup$
0
$\begingroup$

Rosanswers logo

Yes that is possible;

For instance;

from ament_index_python.packages import get_package_share_directory
import os
os.environ['GAZEBO_MODEL_PATH'] = os.path.join(get_package_share_directory('your_gazebo_pkg'),'models')

Originally posted by Fetullah Atas with karma: 819 on 2022-03-01

This answer was NOT ACCEPTED on the original site

Post score: 1


Original comments

Comment by joseecm on 2022-03-01:
Hello, thanks for your answer.

Using the following line on the code also doesn't work:

os.environ['GAZEBO_MODEL_PATH'] = '/home/ros/Documents/ROS2/ros2_ws/install/mars_robot/share/mars_robot'

There must be any difference between setting an environment variable using export and doing it inside launch file because one way works but the other not.

Comment by Fetullah Atas on 2022-03-01:
Are you sure you are marking the models folder for installation in your CmakeLists ?

Comment by Fetullah Atas on 2022-03-01:
You need to collect all your gazebo models in one folder named “models”, you also need to make sure this folder is installed alongside maybe your “launch” folder in CmakeLists. Finally, you need append your path with “models” as well, “…mars_robot/models/“

Comment by joseecm on 2022-03-01:
I have no CmakeLists because it is a python package.

$\endgroup$
0
$\begingroup$

Rosanswers logo

When things don't seem to make sense, it's better to stop and review those seemingly unimportant things that you don't doubt you're doing right, because you're probably making a silly mistake. And that is precisely what was happening to me. Both the use of SetEnvironmentVariable and os.environ work correctly when I use them inside the launch file. The problem was that to save typing the same thing many times in the console, I was using the option to reuse previous commands and I didn't realize that I was executing another launch file that had the same name except for one character. That's why no matter what I modified in the code it never worked.

The following code works perfectly:

import os
import xacro

from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription 
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Node
from launch.actions import SetEnvironmentVariable

def generate_launch_description():

    pkg_install_path = get_package_share_directory('mars_robot')

    if 'GAZEBO_MODEL_PATH' in os.environ:
        model_path =  os.environ['GAZEBO_MODEL_PATH'] + ':' + pkg_install_path
    else:
        model_path =  pkg_install_path

    gazebo = IncludeLaunchDescription(
                PythonLaunchDescriptionSource([os.path.join(
                    get_package_share_directory('gazebo_ros'), 'launch'), '/gazebo.launch.py']),
             )

    xacro_robot_pkg_path = os.path.join(
        get_package_share_directory('mars_robot'))

    xacro_file = os.path.join(xacro_robot_pkg_path,
                              'urdf',
                              'mars_robot.xacro')

    doc = xacro.parse(open(xacro_file))
    xacro.process_doc(doc)
    params = {'robot_description': doc.toxml()}

    node_robot_state_publisher = Node(
        package='robot_state_publisher',
        executable='robot_state_publisher',
        output='screen',
        parameters=[params]
    )

    spawn_entity = Node(package='gazebo_ros', executable='spawn_entity.py',
                        arguments=['-topic', 'robot_description',
                                   '-entity', 'mars_robot'],
                        output='screen')

    return LaunchDescription([
        SetEnvironmentVariable(name='GAZEBO_MODEL_PATH', value=model_path),
        gazebo,
        node_robot_state_publisher,
        spawn_entity,
    ])

Thanks to @ljaniec and @Fetullah Atas for their help, they both gave me a correct solution and allowed me to learn a bit more.


Originally posted by joseecm with karma: 130 on 2022-03-01

This answer was NOT ACCEPTED on the original site

Post score: 1

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.