Configuration Helpers in the Artefacts Toolkit
The Artefacts Toolkit Configuration Helpers are functions that allow you to interact with configurations you have set in your artefacts.yaml file.
Import with:
from artefacts_toolkit.config import get_artefacts_param
Functions
Function Reference
get_artefacts_param
Returns a parameter set in the artefacts.yaml file. If param_type is set to launch, it will be returned as type string so that it can be used as a ROS launch argument.
This function is particularly useful for parametric testing. When you define a list of parameter values in your artefacts.yaml file (e.g., launch/world: ["empty.sdf", "bookstore.sdf", "restaurant.sdf"]), the artefacts run command will execute your test multiple times - once for each value in the list. During each test execution, get_artefacts_param("launch", "world") will automatically return the current parameter value for that specific test run.
This becomes especially powerful for grid-based testing! With three parameters that each have three possible values, Artefacts will automatically execute your test 27 times (3 × 3 × 3) while your launch file code remains unchanged.
get_artefacts_param(
param_type,
param_name,
default=None,
is_ros=True
)
Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
param_type |
str |
The namespace/category of the parameter (e.g., “launch” in “launch/world”) | Required |
param_name |
str |
The specific parameter name (e.g., “world” in “launch/world”) | Required |
default |
any |
Value to return if the parameter isn’t found in artefacts.yaml. | None |
is_ros |
bool |
Whether the parameter should be converted to a ROS parameter format | True |
Returns
The function returns the parameter value with the following behavior:
- If
param_typeis"launch"andis_rosisTrue: Returns the value as astr, regardless of its original type in theartefacts.yamlfile. This is so that it can be used as a ros launch argument. - if
defaultis set to anything other thanNone, then the value will be returned if artefacts is unable to find the requested parameter. This can be useful when (for example) usinglaunch_testinstead ofartefacts runbut you do not wish to make any code changes. It will also preventKeyErrorexceptions. - For all other cases: Returns the value with its original type from the YAML file (e.g.,
list,dict,int,float,str, etc.)
Note
- Currently only supports ROS Params / ROS launch arguments.
- Parametric tests will execute sequentially when running artefacts locally. When running on the platform, they will run in parallel (the maximum number of concurrent tests is determined by your subscription plan).
Example
Given an artefacts.yaml file with the following configuration set:
scenarios:
defaults:
output_dirs: ["output"]
metrics:
- /odometry_error
params:
launch/world: ["bookstore.sdf", "empty.sdf"]
Getting the parameter in our test launch file like so:
def generate_test_description():
try:
world = get_artefacts_param("launch", "world")
except FileNotFoundError:
world = "empty.world"
run_headless = LaunchConfiguration("run_headless")
launch_navigation_stack = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
[
os.path.join(
get_package_share_directory("sam_bot_nav2_gz"),
"launch",
"complete_navigation.launch.py"
),
]
),
launch_arguments=[("run_headless", run_headless), ("world_file", world)],
)
...# Rest of launch test file
This will run the same test twice - once in an empty world and once in a bookstore world - without any changes to your launch file code between runs.
get_artefacts_params
Loads all parameters set in artefacts.yaml for a given run, providing them as dict. Can be used with regular dict methods such as .get()
get_artefacts_params()
Parameters
None
Returns
The function returns all parameters for a given run as type dict.
Note
What is returned will differ depending on whether you are using launch_test_file or run in your artefacts.yaml file to point to your test file. With launch_test_file the parameters will be “rosified”, while with run they will not. As an example:
scenarios:
defaults:
output_dirs: ["output"]
metrics:
- /odometry_error
params:
my_test_node/parameter_1: [0.1, 0.2]
my_test_node/parameter_2: ["a", "b"]
will return the following when using launch_test_file:
# Run 1
{
'my_test_node': {
'ros__parameters': {
'parameter_1': 0.1,
'parameter_2': 'a'
}
}
}
# Run 2
{
'my_test_node': {
'ros__parameters': {
'parameter_1': 0.2,
'parameter_2': 'b'
}
}
}
and the following when using run:
# Run 1
{
'my_test_node/parameter_1': 0.1,
'my_test_node/parameter_2': 'a'
}
# Run 2
{
'my_test_node/parameter_1': 0.2,
'my_test_node/parameter_2': 'b'
}
Example
Given an artefacts.yaml file with the following configuration set:
scenarios:
defaults:
params:
headless: "True"
We can set a flag on our launch_description for a headless simulation as follows:
@launch_pytest.fixture(scope="module")
def launch_description(rosbag_recording):
pkg_path = Path(get_package_share_directory("my_package"))
try:
headless = get_artefacts_params().get("headless", "False")
except RuntimeError:
# If artefacts params are not available, default to False
headless = "False"
start_launch = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
str(pkg_path / "launch" / "mytestfile.launch.py")
),
launch_arguments={
"headless": headless,
}.items(),
)
merge_ros_params_files
Merges two ROS2 yaml parameter files into one, overriding the values in the first one (source) with the values in override
merge_ros_params_files(
source,
override,
destination,
rosify=False
)
Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
source |
str |
Path to original parameter file to be overridden | Required |
override |
str |
Path to parameter file containing parameters to override | Required |
destination |
str |
Path to where new parameter file should be saved | Required |
rosify |
bool |
Converts params to ros2 param file nested format if True |
False |
Returns
None: The newly made merged parameter file will be available at the path specified in destination
Example
Given the following source and override yaml:
# source
outer:
inner1: 1
inner2:
leaf: keep
flat: src
# override
outer:
inner2:
leaf: replaced
new_leaf: 321
inner3: added
flat: override
We will get the following new yaml file saved to destination as follows:
# rosify=False (Default)
outer:
inner1: 1
inner2:
leaf: replaced
new_leaf: 321
inner3: added
flat: override
With rosify=True, parameters will be nested under ros__parameters for the appropriate node:
#source
controller_server:
ros__parameters:
enable_stamped_cmd_vel: true
controller_frequency: 20.0
min_x_velocity_threshold: 0.001
#override
controller_server/controller_frequency: 30
controller_server/min_x_velocity_threshold: 0.005
controller_server/min_y_velocity_threshold: 0.5
#destination
controller_server:
ros__parameters:
enable_stamped_cmd_vel: true
controller_frequency: 30
min_x_velocity_threshold: 0.005
min_y_velocity_threshold: 0.5