18 #include <Eigen/Dense> 25 #include <gazebo/gazebo.hh> 26 #include <gazebo/common/common.hh> 27 #include <gazebo/msgs/msgs.hh> 29 #include <ignition/math/Pose3.hh> 30 #include <ignition/math/Vector2.hh> 31 #include <ignition/math/Vector3.hh> 43 std::ostream& operator<<(std::ostream& os, const std::vector<double>& _vec)
45 for (
auto&& v : _vec )
143 this->angularFrequency = 2.0 * M_PI / this->
period;
145 Physics::DeepWaterDispersionToWavenumber(this->angularFrequency);
146 this->wavelength = 2.0 * M_PI / this->
wavenumber;
149 this->angularFrequencies.clear();
150 this->amplitudes.clear();
151 this->phases.clear();
152 this->wavenumbers.clear();
153 this->steepnesses.clear();
154 this->directions.clear();
156 for (
size_t i = 0; i < this->
number; ++i)
158 const int n = i - this->number/2;
159 const double scaleFactor = std::pow(this->scale, n);
160 const double a = scaleFactor * this->
amplitude;
161 const double k = this->wavenumber / scaleFactor;
163 const double phi = this->
phase;
167 q = std::min(1.0, this->steepness / (a * k * this->number));
170 this->amplitudes.push_back(a);
171 this->angularFrequencies.push_back(omega);
172 this->phases.push_back(phi);
173 this->steepnesses.push_back(q);
174 this->wavenumbers.push_back(k);
177 const double c = std::cos(n * this->angle);
178 const double s = std::sin(n * this->angle);
184 const ignition::math::Vector2d
d(
185 c * this->direction.X() - s * this->direction.Y(),
186 s * this->direction.X() + c * this->direction.Y());
187 directions.push_back(
d);
192 public:
double pm(
double omega,
double omega_p)
194 double alpha = 0.0081;
196 return alpha*std::pow(g, 2.0)/std::pow(omega, 5.0)* \
197 std::exp(-(5.0/4.0)*std::pow(omega_p/omega, 4.0));
207 this->angularFrequency = 2.0 * M_PI / this->
period;
209 Physics::DeepWaterDispersionToWavenumber(this->angularFrequency);
210 this->wavelength = 2.0 * M_PI / this->
wavenumber;
213 this->angularFrequencies.clear();
214 this->amplitudes.clear();
215 this->phases.clear();
216 this->wavenumbers.clear();
217 this->steepnesses.clear();
218 this->directions.clear();
221 std::vector<double> omega_spacing;
222 omega_spacing.push_back(this->angularFrequency*(1.0-1.0/this->scale));
223 omega_spacing.push_back(this->angularFrequency* \
224 (this->scale-1.0/this->scale)/2.0);
225 omega_spacing.push_back(this->angularFrequency*(this->scale-1.0));
227 for (
size_t i = 0; i < this->
number; ++i)
230 const double scaleFactor = std::pow(this->scale, n);
231 const double omega = this->angularFrequency*scaleFactor;
232 const double pms =
pm(omega, this->angularFrequency);
233 const double a = this->gain*std::sqrt(2.0*pms*omega_spacing[i]);
235 const double phi = this->
phase;
239 q = std::min(1.0, this->steepness / (a * k * this->number));
242 this->amplitudes.push_back(a);
243 this->angularFrequencies.push_back(omega);
244 this->phases.push_back(phi);
245 this->steepnesses.push_back(q);
246 this->wavenumbers.push_back(k);
249 const double c = std::cos(n * this->angle);
250 const double s = std::sin(n * this->angle);
256 const ignition::math::Vector2d
d(
257 c * this->direction.X() - s * this->direction.Y(),
258 s * this->direction.X() + c * this->direction.Y());
259 directions.push_back(
d);
265 if (!this->model.compare(
"PMS"))
267 gzmsg <<
"Using Pierson-Moskowitz spectrum sampling wavefield model " 271 else if (!this->model.compare(
"CWR"))
273 gzmsg <<
"Using Constant wavelength-ampltude ratio wavefield model " 279 gzwarn<<
"Wavefield model specified as <" << this->model
280 <<
"> which is not one of the two supported wavefield models: " 281 <<
"PMS or CWR!!!" << std::endl;
296 this->
data->Recalculate();
305 this->
data->amplitude);
311 this->
data->direction);
317 this->
data->steepness);
322 this->
data->Recalculate();
327 return this->
data->number;
332 return this->
data->angle;
337 return this->
data->scale;
342 return this->
data->steepness;
347 return this->
data->angularFrequency;
352 return this->
data->amplitude;
357 return this->
data->period;
362 return this->
data->phase;
367 return this->
data->wavelength;
372 return this->
data->wavenumber;
377 return this->
data->tau;
382 return this->
data->gain;
387 return this->
data->direction;
392 this->
data->number = _number;
393 this->
data->Recalculate();
398 this->
data->angle = _angle;
399 this->
data->Recalculate();
404 this->
data->scale = _scale;
405 this->
data->Recalculate();
410 this->
data->steepness = _steepness;
411 this->
data->Recalculate();
416 this->
data->amplitude = _amplitude;
417 this->
data->Recalculate();
422 this->
data->period = _period;
423 this->
data->Recalculate();
428 this->
data->phase = _phase;
429 this->
data->Recalculate();
434 this->
data->tau = _tau;
438 this->
data->gain = _gain;
443 this->
data->direction = _direction;
444 this->
data->Recalculate();
449 return this->
data->angularFrequencies;
454 return this->
data->amplitudes;
459 return this->
data->phases;
464 return this->
data->steepnesses;
469 return this->
data->wavenumbers;
472 const std::vector<ignition::math::Vector2d>& \
473 WaveParameters::Direction_V()
const 475 return this->
data->directions;
480 gzmsg <<
"Input Parameters:" << std::endl;
481 gzmsg <<
"model: " << this->
data->model << std::endl;
482 gzmsg <<
"number: " << this->
data->number << std::endl;
483 gzmsg <<
"scale: " << this->
data->scale << std::endl;
484 gzmsg <<
"angle: " << this->
data->angle << std::endl;
485 gzmsg <<
"steepness: " << this->
data->steepness << std::endl;
486 gzmsg <<
"amplitude: " << this->
data->amplitude << std::endl;
487 gzmsg <<
"period: " << this->
data->period << std::endl;
488 gzmsg <<
"direction: " << this->
data->direction << std::endl;
489 gzmsg <<
"tau: " << this->
data->tau << std::endl;
490 gzmsg <<
"gain: " << this->
data->gain << std::endl;
491 gzmsg <<
"Derived Parameters:" << std::endl;
492 gzmsg <<
"amplitudes: " << this->
data->amplitudes << std::endl;
493 gzmsg <<
"wavenumbers: " << this->
data->wavenumbers << std::endl;
494 gzmsg <<
"omegas: " << this->
data->angularFrequencies << std::endl;
495 gzmsg <<
"periods: ";
496 for (
auto&& omega : this->
data->angularFrequencies)
498 gzmsg << 2.0 * M_PI / omega <<
", ";
501 gzmsg <<
"phases: " << this->
data->phases << std::endl;
502 gzmsg <<
"steepnesses: " << this->
data->steepnesses << std::endl;
503 gzmsg <<
"directions: ";
504 for (
auto&&
d : this->
data->directions)
516 const ignition::math::Vector3d& _point,
522 for (std::size_t ii = 0; ii < _waveParams.
Number(); ++ii)
528 double dot = _point.X()*dx + _point.Y()*dy;
530 double theta = k*dot - omega*time;
531 double c = cos(theta);
536 return h*(1-exp(-1.0*(time-time_init)/_waveParams.
Tau()));
541 const ignition::math::Vector3d& _point,
549 const std::vector<double>& _a,
550 const std::vector<double>& _k,
551 const std::vector<double>& _omega,
552 const std::vector<double>& _phi,
553 const std::vector<double>& _q,
554 const std::vector<ignition::math::Vector2d>& _dir) :
555 a(_a), k(_k), omega(_omega), phi(_phi), q(_q), dir(_dir) {}
557 const std::vector<double>& a;
558 const std::vector<double>& k;
559 const std::vector<double>& omega;
560 const std::vector<double>& phi;
561 const std::vector<double>& q;
562 const std::vector<ignition::math::Vector2d>& dir;
567 auto wave_fdf = [=](
auto x,
auto p,
auto t,
auto& wp,
auto& F,
auto& J)
570 F(0) = p.x() -
x.x();
571 F(1) = p.y() -
x.y();
576 const size_t n = wp.a.size();
577 for (
auto&& i = 0; i < n; ++i)
579 const double dx = wp.dir[i].X();
580 const double dy = wp.dir[i].Y();
581 const double q = wp.q[i];
582 const double a = wp.a[i];
583 const double k = wp.k[i];
584 const double dot =
x.x() * dx +
x.y() * dy;
585 const double theta = k * dot - wp.omega[i] * t;
586 const double s = std::sin(theta);
587 const double c = std::cos(theta);
588 const double qakc = q * a * k * c;
589 const double df1x = qakc * dx * dx;
590 const double df1y = qakc * dx * dy;
591 const double df2x = df1y;
592 const double df2y = qakc * dy * dy;
602 return pz * (1-exp(-1.0*(time-time_init)/_waveParams.
Tau()));
608 auto solver = [=](
auto& fdfunc,
auto x0,
auto p,
auto t, \
609 auto& wp,
auto tol,
auto nmax)
617 while (std::abs(err) > tol && n < nmax)
619 pz = fdfunc(x0, p, t, wp, F, J);
620 xn = x0 - J.inverse() * F;
638 const double tol = 1.0E-10;
639 const double nmax = 30;
643 Eigen::Vector2d p2(_point.X(), _point.Y());
644 const double pz = solver(wave_fdf, p2, p2, time, wp, tol, nmax);
const std::vector< double > & Amplitude_V() const
Access the component amplitudes.
float Tau() const
Time-constant for starting waves.
double angle
Set the angle between component waves and the mean direction.
void SetPhase(double _phase)
Set the mean wave phase.
void SetPeriod(double _period)
Set the mean wave period. Must be positive.
void SetDirection(const ignition::math::Vector2d &_direction)
Set the mean wave direction.
double Steepness() const
A parameter in [0, 1] controlling the wave steepness with 1 being steepest.
double wavenumber
The mean wavenumber (derived).
static ignition::math::Vector2d Normalize(const ignition::math::Vector2d &_v)
Normalise a Vector2 (i.e. ensure it has unit length)
double Amplitude() const
The amplitude of the mean wave in [m].
This file defines utilities for extracting parameters from SDF.
static ignition::math::Vector2d SdfParamVector2(sdf::Element &_sdf, const std::string &_paramName, const ignition::math::Vector2d _defaultVal)
Extract a named Vector2 parameter from an SDF element.
std::vector< ignition::math::Vector2d > directions
The component wave dirctions (derived).
double amplitude
The mean wave amplitude [m].
static std::string SdfParamString(sdf::Element &_sdf, const std::string &_paramName, const std::string &_defaultVal)
Extract a named string parameter from an SDF element.
size_t Number() const
The number of wave components (3 max if visualisation required).
double Wavelength() const
The mean wavelength.
void SetTau(double _tau)
Set the time constant.
std::vector< double > phases
The component wave phases (derived).
std::shared_ptr< WaveParametersPrivate > data
void SetGain(double _gain)
Set the PMS amplitude multiplier.
This file contains definitions for the physics models.
static double DeepWaterDispersionToWavenumber(double _omega)
Compute the deep water dispersion.
This file contains methods to calculate properties of simple geometrical objects. ...
double Angle() const
The angle between the mean wave direction and the largest / smallest component waves.
size_t number
The number of component waves.
ignition::math::Vector2d Direction() const
A two component vector specifiying the direction.
WaveParameters()
Constructor.
A class to manage the parameters for generating a wave.
void DebugPrint() const
Print a summary of the wave parameters to the gzmsg stream.
const std::vector< ignition::math::Vector2d > & Direction_V() const
Access the component directions.
static double SdfParamDouble(sdf::Element &_sdf, const std::string &_paramName, const double _defaultVal)
Extract a named double parameter from an SDF element.
double Phase() const
The phase of the mean wave.
void SetFromSDF(sdf::Element &_sdf)
Set the parameters from an SDF Element tree.
std::vector< double > wavenumbers
The component wavenumbers (derived).
void SetAmplitude(double _amplitude)
Set the mean wave amplitude. Must be positive.
ignition::math::Vector2d direction
The mean wave direction.
double AngularFrequency() const
The angular frequency.
WaveParametersPrivate()
Constructor.
void SetSteepness(double _steepness)
Set the steepness parameter controlling the steepness of the waves. In [0, 1].
std::vector< double > amplitudes
The component wave amplitudes (derived).
static double ComputeDepthDirectly(const WaveParameters &_waveParams, const ignition::math::Vector3d &_point, double time, double time_init=0)
Compute the depth at a point directly.
double phase
The mean wave phase (not currently enabled).
const std::vector< double > & Wavenumber_V() const
Access the component wavenumbers.
double Scale() const
The scale between the mean and largest / smallest component waves.
TFSIMD_FORCE_INLINE const tfScalar & x() const
void RecalculatePms()
Recalculate for Pierson-Moskowitz spectrum sampling model.
float Gain() const
Amplitude multiplier for PMS.
double wavelength
The mean wavelength (derived).
void SetNumber(size_t _number)
Set the number of wave components (3 max).
TFSIMD_FORCE_INLINE tfScalar dot(const Quaternion &q1, const Quaternion &q2)
const std::vector< double > & Steepness_V() const
Access the steepness components.
static double ComputeDepthSimply(const WaveParameters &_waveParams, const ignition::math::Vector3d &_point, double time, double time_init=0)
std::vector< double > steepnesses
The component wave steepness factors (derived).
double steepness
Control the wave steepness. 0 is sine waves, 1 is Gerstner waves.
std::string model
Name of wavefield model to use - must be "PMS" or "CWR".
double angularFrequency
The mean wave angular frequency (derived).
void RecalculateCmr()
Recalculate for constant wavelength-amplitude ratio.
double tau
The time constant for exponential increasing waves on startup.
This file contains definitions for classes used to manage a wave field. This includes wave parameters...
const std::vector< double > & Phase_V() const
Access the component phases.
double period
The mean wave period [s].
void Recalculate()
Recalculate all derived quantities from inputs.
std::vector< double > angularFrequencies
The component wave angular frequencies (derived).
double scale
Set the scale of the largest and smallest waves.
~WaveParameters()
Destructor.
double Wavenumber() const
The mean wavenumber.
void SetScale(double _scale)
Set the scale parameter controlling the range of amplitudes of the component waves.
double Period() const
The period of the mean wave in [s].
static size_t SdfParamSizeT(sdf::Element &_sdf, const std::string &_paramName, const size_t _defaultVal)
Extract a named size_t parameter from an SDF element.
double pm(double omega, double omega_p)
double gain
The multiplier applied to PM spectra.
const std::vector< double > & AngularFrequency_V() const
Access the component angular frequencies.
A collection of static methods for various physics calculations.
static double DeepWaterDispersionToOmega(double _wavenumber)
Compute the deep water dispersion.
void SetAngle(double _angle)
Set the angle parameter controlling the direction of the component waves.