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)

write version

Parameters:

name – name of the Parameter

Returns:

Parameter

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

Parameters:
  • name – name of the Parameter

  • default_value – default value

Returns:

Parameter

const Parameter &operator()(const std::string &name) const

read only version

Parameters:

name – name of the Parameter

Returns:

Parameter

ParameterContainer &operator[](const std::string &name)
Parameters:

name – name of the child ParameterContainer

Returns:

child ParameterContainer

std::shared_ptr<ParameterContainer> getChildSharedPointer(const std::string &name)
Parameters:

name – name of the child ParameterContainer

Returns:

shared pointer of child ParameterContainer

void loadFromPackageParameterFile(const std::string &package_name, const std::string &param_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

class Parameter

Public Types

enum class Dtype : int

parameter data types

Values:

enumerator STRING
enumerator DOUBLE
enumerator BOOL
enumerator INT
enumerator VECTOR_DOUBLE
enumerator VECTOR_STRING
enumerator VECTOR_INT
enumerator UNDEFINED

Public Static Functions

static inline std::string dTypeToString(Dtype dtype)
Parameters:

dtype – data type

Returns:

data type in string

static Dtype stringToDtype(const std::string &type)
Parameters:

type – data type in string

Returns:

data type in Dtype