Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
noise_generator.cpp
1 // Copyright (c) 2022 Samsung Research America, @artofnothingness Alexey Budyakov
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "nav2_mppi_controller/tools/noise_generator.hpp"
16 
17 #include <memory>
18 #include <mutex>
19 
20 namespace mppi
21 {
22 
24  mppi::models::OptimizerSettings & settings, bool is_holonomic,
25  const std::string & name, ParametersHandler * param_handler)
26 {
27  settings_ = settings;
28  is_holonomic_ = is_holonomic;
29  active_ = true;
30 
31  ndistribution_vx_ = std::normal_distribution(0.0f, settings_.sampling_std.vx);
32  ndistribution_vy_ = std::normal_distribution(0.0f, settings_.sampling_std.vy);
33  ndistribution_wz_ = std::normal_distribution(0.0f, settings_.sampling_std.wz);
34 
35  auto getParam = param_handler->getParamGetter(name);
36  getParam(regenerate_noises_, "regenerate_noises", false);
37 
38  if (regenerate_noises_) {
39  noise_thread_ = std::thread(std::bind(&NoiseGenerator::noiseThread, this));
40  } else {
42  }
43 }
44 
46 {
47  active_ = false;
48  ready_ = true;
49  noise_cond_.notify_all();
50  if (noise_thread_.joinable()) {
51  noise_thread_.join();
52  }
53 }
54 
56 {
57  // Trigger the thread to run in parallel to this iteration
58  // to generate the next iteration's noises (if applicable).
59  {
60  std::unique_lock<std::mutex> guard(noise_lock_);
61  ready_ = true;
62  }
63  noise_cond_.notify_all();
64 }
65 
67  models::State & state,
68  const models::ControlSequence & control_sequence)
69 {
70  std::unique_lock<std::mutex> guard(noise_lock_);
71 
72  state.cvx = noises_vx_.rowwise() + control_sequence.vx.transpose();
73  state.cvy = noises_vy_.rowwise() + control_sequence.vy.transpose();
74  state.cwz = noises_wz_.rowwise() + control_sequence.wz.transpose();
75 }
76 
77 void NoiseGenerator::reset(mppi::models::OptimizerSettings & settings, bool is_holonomic)
78 {
79  settings_ = settings;
80  is_holonomic_ = is_holonomic;
81 
82  // Recompute the noises on reset, initialization, and fallback
83  {
84  std::unique_lock<std::mutex> guard(noise_lock_);
85  ndistribution_vx_ = std::normal_distribution(0.0f, settings_.sampling_std.vx);
86  ndistribution_vy_ = std::normal_distribution(0.0f, settings_.sampling_std.vy);
87  ndistribution_wz_ = std::normal_distribution(0.0f, settings_.sampling_std.wz);
88  noises_vx_.setZero(settings_.batch_size, settings_.time_steps);
89  noises_vy_.setZero(settings_.batch_size, settings_.time_steps);
90  noises_wz_.setZero(settings_.batch_size, settings_.time_steps);
91  ready_ = true;
92  }
93 
94  if (regenerate_noises_) {
95  noise_cond_.notify_all();
96  } else {
98  }
99 }
100 
102 {
103  do {
104  std::unique_lock<std::mutex> guard(noise_lock_);
105  noise_cond_.wait(guard, [this]() {return ready_;});
106  ready_ = false;
108  } while (active_);
109 }
110 
112 {
113  auto & s = settings_;
114  noises_vx_ = Eigen::ArrayXXf::NullaryExpr(
115  s.batch_size, s.time_steps, [&]() {return ndistribution_vx_(generator_);});
116  noises_wz_ = Eigen::ArrayXXf::NullaryExpr(
117  s.batch_size, s.time_steps, [&]() {return ndistribution_wz_(generator_);});
118  if (is_holonomic_) {
119  noises_vy_ = Eigen::ArrayXXf::NullaryExpr(
120  s.batch_size, s.time_steps, [&]() {return ndistribution_vy_(generator_);});
121  }
122 }
123 
124 } // namespace mppi
void reset(mppi::models::OptimizerSettings &settings, bool is_holonomic)
Reset noise generator with settings and model types.
void initialize(mppi::models::OptimizerSettings &settings, bool is_holonomic, const std::string &name, ParametersHandler *param_handler)
Initialize noise generator with settings and model types.
void generateNoisedControls()
Generate random controls by gaussian noise with mean in control_sequence_.
void noiseThread()
Thread to execute noise generation process.
void setNoisedControls(models::State &state, const models::ControlSequence &control_sequence)
set noised control_sequence to state controls
void shutdown()
Shutdown noise generator thread.
void generateNextNoises()
Signal to the noise thread the controller is ready to generate a new noised control for the next iter...
Handles getting parameters and dynamic parameter changes.
auto getParamGetter(const std::string &ns)
Get an object to retrieve parameters.
A control sequence over time (e.g. trajectory)
Settings for the optimizer to use.
State information: velocities, controls, poses, speed.
Definition: state.hpp:32