FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
SensorEchosounder.h
1#pragma once
2
281#include "SampledSensor.h"
282
283#include <array>
284#include <fhsim/simobject/SimObject.h>
285#include <fstream>
286#include <marenv/marenv.h>
287#include <memory>
288#include <span>
289#include <string>
290#include <vector>
291
292namespace environment
293{
294class EnvironmentProvider;
295namespace field
296{
297class IntegrableField;
298class ScalarField;
299} // namespace field
300} // namespace environment
301
302class SensorEchosounder : public SimObject
303{
304public:
306 struct Settings
307 {
308 double pingPeriod = 0.5;
309 double maxRangeDown = 150.0;
310 double rayStepSize = 1.0;
311 double rayTolerance = 0.01;
312 double rangeBias = 0.02;
313 double rangeNoiseStd = 0.02;
314 double rangeNoiseRelative = 0.0005;
315
316 double beamWidthDeg = 7.0;
317 int beamSamples = 1;
318
319 double binSize = 1.0;
320 double svFloorDb = -140.0;
322
323 double minRange = 1.0;
324 double bottomOffset = 0.5;
325 double bottomThresholdDb = -30.0;
326
327 unsigned int noiseSeed = 0;
328 };
329
331 struct Reading
332 {
333 double seafloorDistance = 0.0;
334 double seafloorDepth = 0.0;
335 double altitude = 0.0;
336 double valid = 0.0;
337 double pingTime = 0.0;
338 };
339
341 struct Species
342 {
343 std::string name;
344 int handle = -1;
345 std::string speciesKey;
346 std::shared_ptr<const environment::field::ScalarField> field;
347 const environment::field::IntegrableField* integrable = nullptr;
348 double lengthCm = 0.0;
349 std::vector<double> sigmaBsPerKg;
350 };
351
356 SensorEchosounder(std::string simObjectName, ISimObjectCreator* creator);
357
369 SensorEchosounder(std::string simObjectName, const Settings& settings);
370
373
380 static double PerturbRange(double trueRange, const Settings& settings, SensorNoise& noise);
381
390 static bool IsValidRaySearch(double rayStepSize, double rayTolerance);
391
398 static bool IsValidMaxRange(double maxRange);
399
405 static double AltitudeOf(double slantRange, const double beamDirection[3]);
406
413 static int BinCountOf(double range, double binSize);
414
421 static double SampleRangeOf(int bin, double binSize, double beamRange);
422
440 static double DownSampleRangeOf(int bin, double binSize, double bottomRange, double clearance);
441
447 static double BottomClearance(double rayTolerance, const double beamDirection[3]);
448
454 static double BeamPattern(double offAxisRad, double beamWidthDeg);
455
461 static double EquivalentBeamAngle(double beamWidthDeg);
462
467 static double DiskRadiusPerRange(double beamWidthDeg);
468
473 static bool IsDiskBeam(const double axis[3], double halfWidthRad);
474
484 static void DiskConcentrations(const environment::field::IntegrableField& field, const double position[3], const double axis[3],
485 double binSize, double radiusPerRange, std::span<double> concentration);
486
494 static void SampleDirections(const double axis[3], int beamSamples, double ringAngleRad, std::vector<std::array<double, 3>>& directions);
495
504 static int DetectBottomBin(const std::vector<double>& svLinear, double binSize, double beamRange, double minRange, double thresholdDb);
505
516 static double IntegrateOverWindow(std::span<const double> perBin, double binSize, double beamRange, double windowStart, double windowEnd);
517
529 static std::string FieldStatusWarning(const std::string& sensorName, const std::string& fieldName, double depth, marenv::Status status);
530
537 static double NoiseFloorLinear(double noiseSvAt1mDb, double absorptionDbPerKm, double range);
538
540 void OdeFcn(const double dT, const double* const adX, double* const adXDot) const override;
541
546 void AcceptedStep(const double dT, const double* const adX) override;
547
553 void FinalSetup(const double dT, const double* const adX, ISimObjectCreator* const creator) override;
554
555#ifdef FH_VISUALIZATION
565 void RenderInit(Ogre::Root* const ogreRoot, ISimObjectCreator* const creator) override;
566
571 void RenderUpdate(const double dT, const double* const adX) override;
572#endif
573
575 const Reading& HeldReading() const { return m_reading; }
576
578 const Settings& GetSettings() const { return m_settings; }
579
581 const std::vector<Species>& GetSpecies() const { return m_species; }
582
584 const std::vector<double>& DiskRadiiPerRange() const { return m_diskRadiusPerRange; }
585
587 int PingsTaken() const { return m_pingsTaken; }
588
590 const std::vector<double>& Frequencies() const { return m_frequencykHz; }
591
592protected:
594 const double* OutSeafloorDistance(const double dT, const double* const adX);
596 const double* OutSeafloorDepth(const double dT, const double* const adX);
598 const double* OutAltitude(const double dT, const double* const adX);
600 const double* OutValid(const double dT, const double* const adX);
602 const double* OutPingTime(const double dT, const double* const adX);
604 const double* OutSa(const double dT, const double* const adX, const int index);
606 const double* OutIntegratedBiomass(const double dT, const double* const adX, const int index);
607
608private:
610 struct FieldWarnings
611 {
612 bool outOfRange = false;
613 bool error = false;
614 };
615
619 void ReadFrequencyArrays(ISimObjectCreator* const creator);
620
622 void PrepareFrequencyConstants();
623
627 void ReadFileParameters(ISimObjectCreator* const creator);
628
632 void RefuseRemovedParameters(ISimObjectCreator* const creator);
633
637 void ResolveSpecies(ISimObjectCreator* const creator);
638
643 void Ping(double dT, const double* const adX);
644
652 double MeasureBottom(double dT, const double position[3], const double beamDown[3]);
653
661 void UpdateAbsorption(double dT, const double position[3], const double direction[3], double beamRange);
662
670 void FormPingColumns(double dT, const double position[3], const double direction[3], double bottomRange);
671
678 void WriteRow(double dT, const double position[3], size_t channel, const std::vector<double>& svLinear);
679
683 void OpenFileAndWriteHeader(ISimObjectCreator* const creator);
684
685 SampledSensor m_sampler;
686 Settings m_settings;
687
688 std::vector<std::string> m_speciesFieldNames;
689 bool m_autoDiscover = false;
690 std::vector<Species> m_species;
691 std::string m_parameterLibrary;
692
693 std::vector<double> m_frequencykHz;
694 std::vector<double> m_beamWidthDeg;
695 std::vector<double> m_absorptionDbPerKm;
696 bool m_absorptionGiven = false;
697 std::vector<double> m_bottomBackscatterDb;
698 std::vector<double> m_noiseSvAt1mDb;
699 std::vector<double> m_svBiasDb;
700
701 bool m_writeFile = true;
702 std::string m_fileName;
703 int m_flushEveryNPings = 20;
704 int m_svPrecision = 2;
705
706 std::unique_ptr<std::ofstream> m_stream;
707
708 int m_pingsTaken = 0;
709
710 FieldWarnings m_fieldWarned;
711
712 Reading m_reading;
713 std::vector<double> m_sa;
714 std::vector<double> m_integratedBiomass;
715
716 double m_halfWidthRad = 0.0;
717 std::vector<double> m_ringWeight;
718 std::vector<double> m_diskRadiusPerRange;
719 std::vector<size_t> m_diskOfFrequency;
720 std::vector<double> m_svBiasLinear;
721 std::vector<double> m_bottomBackscatterLinear;
722
724 std::vector<std::array<double, 3>> m_directions;
726 std::vector<double> m_axisConcentration;
728 std::vector<double> m_diskConcentration;
730 std::vector<double> m_ringConcentration;
732 std::vector<std::vector<double>> m_svLinear;
734 std::string m_row;
735
736#ifdef FH_VISUALIZATION
737 Ogre::SceneManager* m_sceneMgr = nullptr;
738 Ogre::SceneNode* m_beamNode = nullptr;
739 Ogre::ManualObject* m_beamObject = nullptr;
740#endif
741};
Definition SampledSensor.h:49
Definition SensorEchosounder.h:303
static double NoiseFloorLinear(double noiseSvAt1mDb, double absorptionDbPerKm, double range)
static bool IsDiskBeam(const double axis[3], double halfWidthRad)
static double EquivalentBeamAngle(double beamWidthDeg)
const double * OutSeafloorDepth(const double dT, const double *const adX)
The inferred depth of the seafloor, m.
const double * OutAltitude(const double dT, const double *const adX)
The measured height above the seafloor, m.
const double * OutValid(const double dT, const double *const adX)
One when the last ping found a bottom, zero otherwise.
static int DetectBottomBin(const std::vector< double > &svLinear, double binSize, double beamRange, double minRange, double thresholdDb)
const std::vector< double > & Frequencies() const
The operating frequencies, kHz.
Definition SensorEchosounder.h:590
static double SampleRangeOf(int bin, double binSize, double beamRange)
static double AltitudeOf(double slantRange, const double beamDirection[3])
void FinalSetup(const double dT, const double *const adX, ISimObjectCreator *const creator) override
static double PerturbRange(double trueRange, const Settings &settings, SensorNoise &noise)
int PingsTaken() const
The number of pings taken so far.
Definition SensorEchosounder.h:587
static double BeamPattern(double offAxisRad, double beamWidthDeg)
const double * OutSeafloorDistance(const double dT, const double *const adX)
The measured slant range to the seafloor, m.
static double BottomClearance(double rayTolerance, const double beamDirection[3])
const std::vector< double > & DiskRadiiPerRange() const
The disk radius per range of each distinct beam width, in order of first appearance among the frequen...
Definition SensorEchosounder.h:584
static double IntegrateOverWindow(std::span< const double > perBin, double binSize, double beamRange, double windowStart, double windowEnd)
SensorEchosounder(std::string simObjectName, const Settings &settings)
static int BinCountOf(double range, double binSize)
static double DiskRadiusPerRange(double beamWidthDeg)
void OdeFcn(const double dT, const double *const adX, double *const adXDot) const override
Writes no derivatives: this SimObject declares no states.
const double * OutSa(const double dT, const double *const adX, const int index)
sa over the Integration window at one frequency, m^2/m^2.
SensorEchosounder(std::string simObjectName, ISimObjectCreator *creator)
const std::vector< Species > & GetSpecies() const
The species entering the acoustic model, in file column order.
Definition SensorEchosounder.h:581
const Reading & HeldReading() const
The reading currently held on the output ports.
Definition SensorEchosounder.h:575
static void DiskConcentrations(const environment::field::IntegrableField &field, const double position[3], const double axis[3], double binSize, double radiusPerRange, std::span< double > concentration)
static void SampleDirections(const double axis[3], int beamSamples, double ringAngleRad, std::vector< std::array< double, 3 > > &directions)
static std::string FieldStatusWarning(const std::string &sensorName, const std::string &fieldName, double depth, marenv::Status status)
static double DownSampleRangeOf(int bin, double binSize, double bottomRange, double clearance)
const double * OutIntegratedBiomass(const double dT, const double *const adX, const int index)
The Integrated biomass of one species field, kg/m^2.
~SensorEchosounder() override
Flushes and closes the echogram file, and releases the visualisation geometry.
static bool IsValidMaxRange(double maxRange)
const double * OutPingTime(const double dT, const double *const adX)
The time of the ping the held reading came from, s.
static bool IsValidRaySearch(double rayStepSize, double rayTolerance)
void AcceptedStep(const double dT, const double *const adX) override
const Settings & GetSettings() const
The settings the instrument was built with.
Definition SensorEchosounder.h:578
Definition SensorNoise.h:43
Status
Definition marenv.h:40
The altimeter reading held on the output ports between pings.
Definition SensorEchosounder.h:332
double valid
One when a bottom was found, zero otherwise.
Definition SensorEchosounder.h:336
double pingTime
The time of the ping this reading came from, s.
Definition SensorEchosounder.h:337
double seafloorDepth
The inferred depth of the seafloor, m.
Definition SensorEchosounder.h:334
double seafloorDistance
The measured slant range to the seafloor, m.
Definition SensorEchosounder.h:333
double altitude
The measured height above the seafloor, m.
Definition SensorEchosounder.h:335
Everything the instrument is configured with.
Definition SensorEchosounder.h:307
double independentSamplesPerBin
The Gamma shape of the speckle.
Definition SensorEchosounder.h:321
double rayTolerance
The convergence tolerance of the ray intersection, m.
Definition SensorEchosounder.h:311
double rangeNoiseRelative
The relative range noise standard deviation.
Definition SensorEchosounder.h:314
double beamWidthDeg
The widest full beam opening angle, degrees; the drawn cone and the sampling ring.
Definition SensorEchosounder.h:316
double minRange
The start of the Integration window, the near-field limit, m.
Definition SensorEchosounder.h:323
double rangeBias
The constant offset of the measured range, m.
Definition SensorEchosounder.h:312
double bottomOffset
The Integration window ends this far short of the detected bottom, m.
Definition SensorEchosounder.h:324
double svFloorDb
The lowest Sv ever reported, dB.
Definition SensorEchosounder.h:320
int beamSamples
The samples across the beam per range bin: the axis, then a ring.
Definition SensorEchosounder.h:317
double bottomThresholdDb
The Sv a bin needs to be detected as the bottom, dB.
Definition SensorEchosounder.h:325
double rayStepSize
The search step of the ray intersection, m.
Definition SensorEchosounder.h:310
unsigned int noiseSeed
The random seed; zero is a perfect instrument.
Definition SensorEchosounder.h:327
double maxRangeDown
The longest slant range searched and binned, m.
Definition SensorEchosounder.h:309
double rangeNoiseStd
The absolute range noise standard deviation, m.
Definition SensorEchosounder.h:313
double binSize
The echogram range bin size, m.
Definition SensorEchosounder.h:319
double pingPeriod
The time between pings, s.
Definition SensorEchosounder.h:308
One Species Concentration field as the acoustic model sees it.
Definition SensorEchosounder.h:342
std::shared_ptr< const environment::field::ScalarField > field
The field, kept alive here; set at bind time.
Definition SensorEchosounder.h:346
const environment::field::IntegrableField * integrable
field as an IntegrableField (D20), or null: then the species is point sampled.
Definition SensorEchosounder.h:347
int handle
The field handle, resolved once in FinalSetup.
Definition SensorEchosounder.h:344
std::string name
The scalar field name.
Definition SensorEchosounder.h:343
double lengthCm
The field's mean length, cm.
Definition SensorEchosounder.h:348
std::string speciesKey
The field's species, a key of the Parameter library.
Definition SensorEchosounder.h:345
std::vector< double > sigmaBsPerKg
sigma_bs per kg at each frequency, m^2/kg.
Definition SensorEchosounder.h:349