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
90inline void set_diagonal_covariance(std::vector<double>& covariance, double stddev)
91{
92 assert(covariance.size() == 9 && "covariance must be a flat 3x3 (9-element) matrix");
93 covariance[0] = covariance[4] = covariance[8] = stddev * stddev;
94}
95
96namespace detail
97{
98
107template <int N>
108inline Eigen::Matrix<double, N, 1> sample_noise(double stddev, NoiseDistribution distribution, std::mt19937& rng)
109{
110 Eigen::Matrix<double, N, 1> samples;
111 if (distribution == NoiseDistribution::kUniform)
112 {
113 const double bound = stddev * std::sqrt(3.0);
114 std::uniform_real_distribution<double> dist(-bound, bound);
115 for (int i = 0; i < N; ++i)
116 {
117 samples[i] = dist(rng);
118 }
119 }
120 else
121 {
122 std::normal_distribution<double> dist(0.0, stddev);
123 for (int i = 0; i < N; ++i)
124 {
125 samples[i] = dist(rng);
126 }
127 }
128 return samples;
129}
130
131} // namespace detail
132
137inline void add_sensor_noise(Eigen::Vector3d& value, double stddev, NoiseDistribution distribution, std::mt19937& rng)
138{
139 if (stddev <= 0.0)
140 {
141 return;
142 }
143 value += detail::sample_noise<3>(stddev, distribution, rng);
144}
145
153inline void add_sensor_noise(Eigen::Quaterniond& value, double stddev, NoiseDistribution distribution, std::mt19937& rng)
154{
155 if (stddev <= 0.0)
156 {
157 return;
158 }
159 value.coeffs() += detail::sample_noise<4>(stddev, distribution, rng);
160 value.normalize();
161}
162
167inline void add_sensor_noise(Eigen::Vector3d& value, double stddev, NoiseState& noise)
168{
169 add_sensor_noise(value, stddev, noise.distribution, noise.rng);
170}
171
172inline void add_sensor_noise(Eigen::Quaterniond& value, double stddev, NoiseState& noise)
173{
174 add_sensor_noise(value, stddev, noise.distribution, noise.rng);
175}
176
177} // 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:108
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:137
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 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:90
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