10 #define SALUTILITIES_H
15 #include "comparisonop.h"
16 #include "digitalfilter.h"
17 #include "iirfilter.h"
19 #include "elementaryop.h"
34 const T first_element_heading,
35 const RotationDirection direction = RotationDirection::kCounterclockwise) noexcept {
36 std::vector<T> angles(num_elements);
37 T separation = (T) 2.0*
PI/((
Angle) num_elements);
38 if (direction == RotationDirection::kClockwise) {
39 separation = -separation;
42 for (
Int i=0; i<num_elements; ++i) {
43 angles[i] = first_element_heading + separation * ((T) i);
49 template<
class T,
class V>
51 std::vector<V> new_vector(vector.size());
53 new_vector[i] = (V) vector[i];
65 target_triplet_(initial_triplet),
66 current_triplet_(initial_triplet),
67 max_speed_(std::numeric_limits<
Speed>::infinity()),
68 has_reached_target_(true) {
69 ASSERT(std::numeric_limits<Speed>::has_infinity);
70 ASSERT(std::numeric_limits<Speed>::infinity() ==
71 std::numeric_limits<Speed>::infinity());
75 max_speed_ = max_speed;
80 target_triplet_ = triplet;
81 current_triplet_ = triplet;
82 has_reached_target_ =
true;
86 target_triplet_ = target_triplet;
87 has_reached_target_ =
false;
91 return target_triplet_;
95 if (max_speed_ == std::numeric_limits<Speed>::infinity()) {
96 current_triplet_ = target_triplet_;
97 has_reached_target_ =
true;
100 sal::Length speed = Distance(target_triplet_, current_triplet_) /
101 time_elapsed_since_last_tick;
103 if (speed <= max_speed_) {
104 current_triplet_ = target_triplet_;
105 has_reached_target_ =
true;
107 current_triplet_ = PointOnLine(current_triplet_,
109 max_speed_*time_elapsed_since_last_tick);
115 return has_reached_target_;
119 return current_triplet_;
129 bool has_reached_target_;
138 const Time sampling_frequency) noexcept :
139 current_value_(initial_value), target_value_(initial_value),
140 step_(0.0), countdown_(0), sampling_frequency_(sampling_frequency) {
141 ASSERT_WITH_MESSAGE(std::isgreaterequal(sampling_frequency, 0.0),
142 "Sampling frequency cannot be negative ");
146 if (countdown_ <= 0) {
return target_value_; }
148 current_value_ += step_;
149 return current_value_;
154 if ((countdown_-num_jumps+1) <= 0) {
156 return target_value_;
158 countdown_ -= num_jumps;
159 current_value_ += step_*((
Sample)num_jumps);
160 return current_value_;
172 const Int num_samples,
173 Sample* output_data) noexcept {
175 for (
Int i=0; i<num_samples; ++i) {
179 mcl::Multiply(input_data, num_samples, target_value_, output_data);
191 const Int num_samples,
192 Sample* input_output_data) noexcept {
194 for (
Int i=0; i<num_samples; ++i) {
198 for (
Int i=0; i<num_samples; ++i) {
199 input_output_data[i] += input_data[i]*target_value_;
207 const Int num_samples,
208 Sample* output_data)
const noexcept {
211 for (
Int i=0; i<num_samples; ++i) {
215 mcl::Multiply(input_data, num_samples, target_value_, output_data);
222 ASSERT_WITH_MESSAGE(std::isgreaterequal(ramp_time, 0.0),
223 "Ramp time cannot be negative ");
224 if ((mcl::RoundToInt(ramp_time*sampling_frequency_)) == 0) {
232 const Int num_update_samples = mcl::RoundToInt(ramp_time*sampling_frequency_);
233 countdown_ = num_update_samples;
236 if (num_update_samples == 0) {
239 step_ = (target_value_ - current_value_) /
240 ((
Sample) num_update_samples);
254 Time sampling_frequency_;
265 ASSERT_WITH_MESSAGE(std::isgreaterequal(ramp_samples, 0),
266 "Decay constant cannot be negative.");
268 mcl::Real a1 = exp(-1.0/ramp_samples);
269 mcl::Real b0 = 1.0 - a1;
270 filter_ = mcl::IirFilter(mcl::BinaryVector<mcl::Real>(b0, 0.0),
271 mcl::BinaryVector<mcl::Real>(1.0, -a1));
274 virtual mcl::Real
Filter(
const mcl::Real input) noexcept {
275 return filter_.Filter(input);
278 using mcl::DigitalFilter::Filter;
280 virtual void Reset() noexcept { filter_.Reset(); }
283 mcl::IirFilter filter_;
287 template <
typename T>
289 std::ostringstream output;