ros2_control - rolling
Loading...
Searching...
No Matches
utils.hpp
1
20#pragma once
21
22#include <Eigen/Core>
23#include <Eigen/Geometry>
24#include <hardware_interface/hardware_info.hpp>
25#include <rclcpp/rclcpp.hpp>
26
27#include "mujoco_ros2_control/data.hpp"
28
29#include <cassert>
30#include <cmath>
31#include <random>
32#include <string>
33
34namespace mujoco_ros2_control
35{
36
40inline std::optional<hardware_interface::ComponentInfo>
41get_sensor_from_info(const hardware_interface::HardwareInfo& hardware_info, const std::string& name)
42{
43 for (size_t sensor_index = 0; sensor_index < hardware_info.sensors.size(); sensor_index++)
44 {
45 const auto& sensor = hardware_info.sensors.at(sensor_index);
46 if (hardware_info.sensors.at(sensor_index).name == name)
47 {
48 return sensor;
49 }
50 }
51 return std::nullopt;
52}
53
58inline std::string get_sensor_parameter_or(const hardware_interface::ComponentInfo& sensor, const std::string& key,
59 const std::string& default_value)
60{
61 if (auto it = sensor.parameters.find(key); it != sensor.parameters.end())
62 {
63 return it->second;
64 }
65 return default_value;
66}
67
74{
75 const std::string value = get_sensor_parameter_or(sensor, "noise_distribution", "gaussian");
76 if (value != "gaussian" && value != "uniform")
77 {
78 RCLCPP_WARN(rclcpp::get_logger("mujoco_ros2_control"),
79 "Only noise distributions of 'gaussian' or 'uniform' are allowed, but you selected '%s'. "
80 "Defaulting to 'gaussian'.",
81 value.c_str());
82 }
83 return value == "uniform" ? NoiseDistribution::kUniform : NoiseDistribution::kGaussian;
84}
85
92inline void log_sensor_components_noise(const rclcpp::Logger& logger, NoiseDistribution distribution,
93 std::initializer_list<std::pair<const std::string&, double>> components)
94{
95 const char* distribution_name = (distribution == NoiseDistribution::kUniform ? "uniform" : "gaussian");
96 for (const auto& [component_name, noise_stddev] : components)
97 {
98 RCLCPP_INFO(logger, "Sensor component '%s' is using '%s' noise with stddev: %f", component_name.c_str(),
99 distribution_name, noise_stddev);
100 }
101}
102
107inline void set_diagonal_covariance(std::vector<double>& covariance, double stddev)
108{
109 assert(covariance.size() == 9 && "covariance must be a flat 3x3 (9-element) matrix");
110 covariance[0] = covariance[4] = covariance[8] = stddev * stddev;
111}
112
113namespace detail
114{
115
124template <int N>
125inline Eigen::Matrix<double, N, 1> sample_noise(double stddev, NoiseDistribution distribution, std::mt19937& rng)
126{
127 Eigen::Matrix<double, N, 1> samples;
128 if (distribution == NoiseDistribution::kUniform)
129 {
130 const double bound = stddev * std::sqrt(3.0);
131 std::uniform_real_distribution<double> dist(-bound, bound);
132 for (int i = 0; i < N; ++i)
133 {
134 samples[i] = dist(rng);
135 }
136 }
137 else
138 {
139 std::normal_distribution<double> dist(0.0, stddev);
140 for (int i = 0; i < N; ++i)
141 {
142 samples[i] = dist(rng);
143 }
144 }
145 return samples;
146}
147
148} // namespace detail
149
154inline void add_sensor_noise(Eigen::Vector3d& value, double stddev, NoiseDistribution distribution, std::mt19937& rng)
155{
156 if (stddev <= 0.0)
157 {
158 return;
159 }
160 value += detail::sample_noise<3>(stddev, distribution, rng);
161}
162
170inline void add_sensor_noise(Eigen::Quaterniond& value, double stddev, NoiseDistribution distribution, std::mt19937& rng)
171{
172 if (stddev <= 0.0)
173 {
174 return;
175 }
176 value.coeffs() += detail::sample_noise<4>(stddev, distribution, rng);
177 value.normalize();
178}
179
184inline void add_sensor_noise(Eigen::Vector3d& value, double stddev, NoiseState& noise)
185{
186 add_sensor_noise(value, stddev, noise.distribution, noise.rng);
187}
188
189inline void add_sensor_noise(Eigen::Quaterniond& value, double stddev, NoiseState& noise)
190{
191 add_sensor_noise(value, stddev, noise.distribution, noise.rng);
192}
193
194} // namespace mujoco_ros2_control
Eigen::Matrix< double, N, 1 > sample_noise(double stddev, NoiseDistribution distribution, std::mt19937 &rng)
Fills an N-vector with independent zero-mean noise samples of the given standard deviation and shape,...
Definition utils.hpp:125
Definition data.hpp:32
void add_sensor_noise(Eigen::Vector3d &value, double stddev, NoiseDistribution distribution, std::mt19937 &rng)
Adds zero-mean noise, independently sampled per axis, to a 3D vector in place. No-op if stddev is not...
Definition utils.hpp:154
std::optional< hardware_interface::ComponentInfo > get_sensor_from_info(const hardware_interface::HardwareInfo &hardware_info, const std::string &name)
Returns the sensor's component info for the provided sensor name, if it exists.
Definition utils.hpp:41
void log_sensor_components_noise(const rclcpp::Logger &logger, NoiseDistribution distribution, std::initializer_list< std::pair< const std::string &, double > > components)
Logs, at INFO level, the noise distribution and standard deviation configured for each of a sensor's ...
Definition utils.hpp:92
void set_diagonal_covariance(std::vector< double > &covariance, double stddev)
Sets a flat, row-major 3x3 covariance's diagonal to stddev * stddev, leaving off-diagonal terms untou...
Definition utils.hpp:107
NoiseDistribution
Definition data.hpp:206
NoiseDistribution get_noise_distribution(const hardware_interface::ComponentInfo &sensor)
Reads the sensor's noise_distribution parameter ("gaussian" (default) or "uniform")....
Definition utils.hpp:73
std::string get_sensor_parameter_or(const hardware_interface::ComponentInfo &sensor, const std::string &key, const std::string &default_value)
Returns the value of a sensor-level <param> (from the sensor's own ComponentInfo),...
Definition utils.hpp:58
Definition hardware_info.hpp:88
std::unordered_map< std::string, std::string > parameters
(Optional) Key-value pairs of component parameters, e.g. min/max values or serial number.
Definition hardware_info.hpp:111
This structure stores information about hardware defined in a robot's URDF.
Definition hardware_info.hpp:373
std::vector< ComponentInfo > sensors
Definition hardware_info.hpp:403
Definition data.hpp:216