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);
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.
const std::vector< double > & AngularFrequency_V() const
Access the component angular frequencies.
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 Wavenumber() const
The mean wavenumber.
This file defines utilities for extracting parameters from SDF.
double Angle() const
The angle between the mean wave direction and the largest / smallest component waves.
double Period() const
The period of the mean wave in [s].
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.
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.
double Steepness() const
A parameter in [0, 1] controlling the wave steepness with 1 being steepest.
This file contains methods to calculate properties of simple geometrical objects. ...
size_t number
The number of component waves.
double Scale() const
The scale between the mean and largest / smallest component waves.
WaveParameters()
Constructor.
A class to manage the parameters for generating a wave.
static double SdfParamDouble(sdf::Element &_sdf, const std::string &_paramName, const double _defaultVal)
Extract a named double parameter from an SDF element.
void SetFromSDF(sdf::Element &_sdf)
Set the parameters from an SDF Element tree.
std::vector< double > wavenumbers
The component wavenumbers (derived).
const std::vector< double > & Steepness_V() const
Access the steepness components.
void SetAmplitude(double _amplitude)
Set the mean wave amplitude. Must be positive.
float Tau() const
Time-constant for starting waves.
ignition::math::Vector2d direction
The mean wave direction.
const std::vector< double > & Amplitude_V() const
Access the component amplitudes.
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).
float Gain() const
Amplitude multiplier for PMS.
size_t Number() const
The number of wave components (3 max if visualisation required).
void RecalculatePms()
Recalculate for Pierson-Moskowitz spectrum sampling model.
const std::vector< ignition::math::Vector2d > & Direction_V() const
Access the component directions.
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)
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".
const std::vector< double > & Phase_V() const
Access the component phases.
double angularFrequency
The mean wave angular frequency (derived).
void RecalculateCmr()
Recalculate for constant wavelength-amplitude ratio.
double AngularFrequency() const
The angular frequency.
double Phase() const
The phase of the mean wave.
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...
double Amplitude() const
The amplitude of the mean wave in [m].
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.
void SetScale(double _scale)
Set the scale parameter controlling the range of amplitudes of the component waves.
void DebugPrint() const
Print a summary of the wave parameters to the gzmsg stream.
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.
A collection of static methods for various physics calculations.
double Wavelength() const
The mean wavelength.
ignition::math::Vector2d Direction() const
A two component vector specifiying the direction.
const std::vector< double > & Wavenumber_V() const
Access the component wavenumbers.
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.