Parameter
Raisin provides a global parameter tree. The root of this tree is a static variable accessible through the static method ParameterContainer::getRoot()
. Controllers and plugins, which are dynamically loaded, should not directly invoke ParameterContainer::getRoot()
; they should use their own paramRoot_
.
In this tree, nodes can either be Parameter
or ParameterContainer
types. Parameter
nodes are leaf nodes, while ParameterContainer
nodes are not. To navigate to a child ParameterContainer
, you use the []
operator. For a child Parameter
, you use the ()
operator. Accessing a non-existent child node will automatically create that node.
Parameter
nodes support various data types, including STRING, DOUBLE, BOOL, VECTOR, and INT
.
To set a parameter, you simply use the =
operator followed by the appropriate type. When you need to use a parameter, ensure you cast it to the correct type using static_cast<DType>(parameter)
.
The ParameterContainer
can be initialized from a YAML file using the method loadFromPackageParameterFile
. This YAML file should be located in install/config/$PACKAGE_NAME/config/params.yaml
.
The parameter can be overridden by the file located at $HOME/.raisin/$PACKAGE_NAME/params.yaml. When running the executable with sudo su, $HOME is /root.
Here’s an example of how the syntax in the YAML file should look:
test_string:
value: hello
dtype: string
options: [hello, goodbye]
test_double:
value: 5.3
dtype: double
min: 3
max: 5
test_int:
value: 3
dtype: int
test_bool:
value: true
dtype: bool
test_vec_double:
value: [1,2,3]
dtype: vector<double>
test_vec_string:
value: ["hello", "world"]
dtype: vector<string>
test_vec_int:
value: [1,2,3]
dtype: vector<int>
For practical implementation examples, refer to the test_raisin_parameter.cpp
.
// Copyright (c) 2020 Robotics and Artificial Intelligence Lab, KAIST
//
// Any unauthorized copying, alteration, distribution, transmission,
// performance, display or use of this material is prohibited.
//
// All rights reserved.
#include <gtest/gtest.h>
#include <string>
#include "../include/raisin_parameter/parameter_container.hpp"
//
// Tests
//
class Child
{
public:
explicit Child(raisin::parameter::ParameterContainer & param)
: param_(param["Child"])
{
param_("param1").setOptions({"hello", "goodbye"});
param_("param1") = "hello";
Eigen::VectorXd testVec(3);
testVec << 1, 2, 3;
param_("param2") = testVec;
std::vector<std::string> testVecString = {"hello", "world"};
param_("param3") = testVecString;
std::vector<int> testVecInt = {1, 2, 3};
param_("param4") = testVecInt;
}
private:
raisin::parameter::ParameterContainer & param_;
};
class Parent
{
public:
Parent()
: param_(raisin::parameter::ParameterContainer::getRoot()),
child_(raisin::parameter::ParameterContainer::getRoot())
{
param_("param1") = 3;
param_("param2") = true;
}
private:
raisin::parameter::ParameterContainer & param_;
Child child_;
};
TEST(ParameterTest, ParameterTest1)
{
Parent parent;
auto & rootParamContainer = raisin::parameter::ParameterContainer::getRoot();
EXPECT_EQ("hello", std::string(rootParamContainer["Child"]("param1")));
EXPECT_EQ(3, int(rootParamContainer("param1")));
EXPECT_EQ(true, bool(rootParamContainer("param2")));
Eigen::VectorXd testVec = rootParamContainer["Child"]("param2");
EXPECT_EQ(6, testVec.sum());
std::vector<std::string> testVecString = rootParamContainer["Child"]("param3");
EXPECT_EQ("hello", testVecString[0]);
EXPECT_EQ("world", testVecString[1]);
std::vector<int> testVecInt = rootParamContainer["Child"]("param4");
EXPECT_EQ(6, testVecInt[0] + testVecInt[1] + testVecInt[2]);
rootParamContainer["file"].loadFromPackageParameterFile("raisin_parameter", "params.yaml");
EXPECT_EQ(5.3, double(rootParamContainer["file"]("test_double")));
EXPECT_EQ("hello", std::string(rootParamContainer["file"]("test_string")));
EXPECT_EQ(3, int(rootParamContainer["file"]("test_int")));
EXPECT_EQ(true, bool(rootParamContainer["file"]("test_bool")));
Eigen::VectorXd test_vec_true(3), test_vec_read(3);
test_vec_true << 1, 2, 3;
test_vec_read = rootParamContainer["file"]("test_vec_double");
EXPECT_NEAR((test_vec_true - test_vec_read).sum(), 0, 1e-15);
std::vector<double> test_vec_double_true = {1, 2, 3};
std::vector<double> test_vec_double_read = rootParamContainer["file"]("test_vec_double");
for (int i = 0; i < 3; i++) {
EXPECT_NEAR(test_vec_double_true[i], test_vec_double_read[i], 1e-15);
}
std::vector<std::string> test_vec_string_true = {"hello", "world"};
std::vector<std::string> test_vec_string_read = rootParamContainer["file"]("test_vec_string");
for (int i = 0; i < 2; i++) {
EXPECT_EQ(test_vec_string_true[i], test_vec_string_read[i]);
}
std::vector<int> test_vec_int_true = {1, 2, 3};
std::vector<int> test_vec_int_read = rootParamContainer["file"]("test_vec_int");
for (int i = 0; i < 3; i++) {
EXPECT_EQ(test_vec_int_true[i], test_vec_int_read[i]);
}
}
API
-
class ParameterContainer
Public Functions
-
Parameter &operator()(const std::string &name, const std::variant<int, double, const char*, std::string, bool, Eigen::VectorXd, std::vector<double>, std::vector<std::string>, std::vector<int>> &default_value)
write version with default value
-
ParameterContainer &operator[](const std::string &name)
- Parameters:
name – name of the child ParameterContainer
- Returns:
child ParameterContainer
- Parameters:
name – name of the child ParameterContainer
- Returns:
shared pointer of child ParameterContainer
-
void loadFromPackageParameterFile(const std::string &package_name, const std::string ¶m_file_name = "params.yaml")
load parameters from yaml file
- Parameters:
package_name – name of the package
package_file_name – name of the file inside the package(default is “params.yaml”)
-
std::unordered_map<std::string, std::shared_ptr<ParameterContainer>> &getParamContainerList()
- Returns:
names of the child ParameterContainer
Public Static Functions
-
static ParameterContainer &getRoot()
- Returns:
unique root of the parameterContainer
-
Parameter &operator()(const std::string &name, const std::variant<int, double, const char*, std::string, bool, Eigen::VectorXd, std::vector<double>, std::vector<std::string>, std::vector<int>> &default_value)