FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
SensorEchosounder.h
1#pragma once
2
269#include "SampleClock.h"
270#include "SensorFrame.h"
271#include "SensorNoise.h"
272
273#include <array>
274#include <fhsim/simobject/SimObject.h>
275#include <fstream>
276#include <marenv/marenv.h>
277#include <memory>
278#include <span>
279#include <string>
280#include <vector>
281
282namespace environment
283{
284class EnvironmentProvider;
285}
286
287class SensorEchosounder : public SimObject
288{
289public:
291 struct Settings
292 {
293 double pingPeriod = 0.5;
294 double maxRangeDown = 150.0;
295 double rayStepSize = 1.0;
296 double rayTolerance = 0.01;
297 double rangeBias = 0.02;
298 double rangeNoiseStd = 0.02;
299 double rangeNoiseRelative = 0.0005;
300
301 double beamWidthDeg = 7.0;
302 int beamSamples = 1;
303
304 double binSize = 1.0;
305 double svFloorDb = -140.0;
307
308 double minRange = 1.0;
309 double bottomOffset = 0.5;
310 double bottomThresholdDb = -30.0;
311
312 unsigned int noiseSeed = 0;
313 };
314
316 struct Reading
317 {
318 double seafloorDistance = 0.0;
319 double seafloorDepth = 0.0;
320 double altitude = 0.0;
321 double valid = 0.0;
322 double pingTime = 0.0;
323 };
324
326 struct Species
327 {
328 std::string name;
329 int handle = -1;
330 std::string speciesKey;
331 double lengthCm = 0.0;
332 std::vector<double> sigmaBsPerKg;
333 };
334
339 SensorEchosounder(std::string simObjectName, ISimObjectCreator* creator);
340
352 SensorEchosounder(std::string simObjectName, const Settings& settings);
353
356
363 static double PerturbRange(double trueRange, const Settings& settings, SensorNoise& noise);
364
373 static bool IsValidRaySearch(double rayStepSize, double rayTolerance);
374
381 static bool IsValidMaxRange(double maxRange);
382
388 static double AltitudeOf(double slantRange, const double beamDirection[3]);
389
396 static int BinCountOf(double range, double binSize);
397
404 static double SampleRangeOf(int bin, double binSize, double beamRange);
405
423 static double DownSampleRangeOf(int bin, double binSize, double bottomRange, double clearance);
424
430 static double BottomClearance(double rayTolerance, const double beamDirection[3]);
431
437 static double BeamPattern(double offAxisRad, double beamWidthDeg);
438
446 static void SampleDirections(const double axis[3], int beamSamples, double ringAngleRad, std::vector<std::array<double, 3>>& directions);
447
456 static int DetectBottomBin(const std::vector<double>& svLinear, double binSize, double beamRange, double minRange, double thresholdDb);
457
468 static double IntegrateOverWindow(std::span<const double> perBin, double binSize, double beamRange, double windowStart, double windowEnd);
469
481 static std::string FieldStatusWarning(const std::string& sensorName, const std::string& fieldName, double depth, marenv::Status status);
482
489 static double NoiseFloorLinear(double noiseSvAt1mDb, double absorptionDbPerKm, double range);
490
492 void OdeFcn(const double dT, const double* const adX, double* const adXDot) const override;
493
498 void AcceptedStep(const double dT, const double* const adX) override;
499
505 void FinalSetup(const double dT, const double* const adX, ISimObjectCreator* const creator) override;
506
507#ifdef FH_VISUALIZATION
517 void RenderInit(Ogre::Root* const ogreRoot, ISimObjectCreator* const creator) override;
518
523 void RenderUpdate(const double dT, const double* const adX) override;
524#endif
525
527 const Reading& HeldReading() const { return m_reading; }
528
530 const Settings& GetSettings() const { return m_settings; }
531
533 const std::vector<Species>& GetSpecies() const { return m_species; }
534
536 int PingsTaken() const { return m_pingsTaken; }
537
539 const std::vector<double>& Frequencies() const { return m_frequencykHz; }
540
541protected:
543 const double* OutSeafloorDistance(const double dT, const double* const adX);
545 const double* OutSeafloorDepth(const double dT, const double* const adX);
547 const double* OutAltitude(const double dT, const double* const adX);
549 const double* OutValid(const double dT, const double* const adX);
551 const double* OutPingTime(const double dT, const double* const adX);
553 const double* OutSa(const double dT, const double* const adX, const int index);
555 const double* OutIntegratedBiomass(const double dT, const double* const adX, const int index);
556
557private:
559 struct FieldWarnings
560 {
561 bool outOfRange = false;
562 bool error = false;
563 };
564
568 void ReadFrequencyArrays(ISimObjectCreator* const creator);
569
571 void PrepareFrequencyConstants();
572
576 void ReadFileParameters(ISimObjectCreator* const creator);
577
581 void RefuseRemovedParameters(ISimObjectCreator* const creator);
582
586 void ResolveEnvironment(ISimObjectCreator* const creator);
587
591 void ResolveSpecies(ISimObjectCreator* const creator);
592
597 void Ping(double dT, const double* const adX);
598
606 double MeasureBottom(double dT, const double position[3], const double beamDown[3]);
607
615 void UpdateAbsorption(double dT, const double position[3], const double direction[3], double beamRange);
616
624 void FormPingColumns(double dT, const double position[3], const double direction[3], double bottomRange);
625
632 void WriteRow(double dT, const double position[3], size_t channel, const std::vector<double>& svLinear);
633
637 void OpenFileAndWriteHeader(ISimObjectCreator* const creator);
638
640 void Warn(const std::string& text) const;
641
642 SensorFrame m_frame;
643 SampleClock m_pingClock;
644 SensorNoise m_noise;
645 Settings m_settings;
646
647 std::string m_name;
648
649 std::vector<std::string> m_speciesFieldNames;
650 bool m_autoDiscover = false;
651 std::vector<Species> m_species;
652 std::string m_parameterLibrary;
653
654 std::vector<double> m_frequencykHz;
655 std::vector<double> m_beamWidthDeg;
656 std::vector<double> m_absorptionDbPerKm;
657 bool m_absorptionGiven = false;
658 std::vector<double> m_bottomBackscatterDb;
659 std::vector<double> m_noiseSvAt1mDb;
660 std::vector<double> m_svBiasDb;
661
662 bool m_writeFile = true;
663 std::string m_fileName;
664 int m_flushEveryNPings = 20;
665 int m_svPrecision = 2;
666
667 std::unique_ptr<std::ofstream> m_stream;
668
669 environment::EnvironmentProvider* m_environment = nullptr;
670 PrintDuringExec* m_print = nullptr;
671
672 bool m_hasPorts = false;
673 int m_pingsTaken = 0;
674
675 FieldWarnings m_fieldWarned;
676
677 Reading m_reading;
678 std::vector<double> m_sa;
679 std::vector<double> m_integratedBiomass;
680
681 double m_halfWidthRad = 0.0;
682 std::vector<double> m_ringWeight;
683 std::vector<double> m_svBiasLinear;
684 std::vector<double> m_bottomBackscatterLinear;
685
687 std::vector<std::array<double, 3>> m_directions;
689 std::vector<double> m_axisConcentration;
691 std::vector<double> m_ringConcentration;
693 std::vector<std::vector<double>> m_svLinear;
695 std::string m_row;
696
697#ifdef FH_VISUALIZATION
698 Ogre::SceneManager* m_sceneMgr = nullptr;
699 Ogre::SceneNode* m_beamNode = nullptr;
700 Ogre::ManualObject* m_beamObject = nullptr;
701#endif
702};
Definition SampleClock.h:40
Definition SensorEchosounder.h:288
static double NoiseFloorLinear(double noiseSvAt1mDb, double absorptionDbPerKm, double range)
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:539
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:536
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])
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)
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:533
const Reading & HeldReading() const
The reading currently held on the output ports.
Definition SensorEchosounder.h:527
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:530
Definition SensorFrame.h:36
Definition SensorNoise.h:39
Status
Definition marenv.h:40
The altimeter reading held on the output ports between pings.
Definition SensorEchosounder.h:317
double valid
One when a bottom was found, zero otherwise.
Definition SensorEchosounder.h:321
double pingTime
The time of the ping this reading came from, s.
Definition SensorEchosounder.h:322
double seafloorDepth
The inferred depth of the seafloor, m.
Definition SensorEchosounder.h:319
double seafloorDistance
The measured slant range to the seafloor, m.
Definition SensorEchosounder.h:318
double altitude
The measured height above the seafloor, m.
Definition SensorEchosounder.h:320
Everything the instrument is configured with.
Definition SensorEchosounder.h:292
double independentSamplesPerBin
The Gamma shape of the speckle.
Definition SensorEchosounder.h:306
double rayTolerance
The convergence tolerance of the ray intersection, m.
Definition SensorEchosounder.h:296
double rangeNoiseRelative
The relative range noise standard deviation.
Definition SensorEchosounder.h:299
double beamWidthDeg
The widest full beam opening angle, degrees; the drawn cone and the sampling ring.
Definition SensorEchosounder.h:301
double minRange
The start of the Integration window, the near-field limit, m.
Definition SensorEchosounder.h:308
double rangeBias
The constant offset of the measured range, m.
Definition SensorEchosounder.h:297
double bottomOffset
The Integration window ends this far short of the detected bottom, m.
Definition SensorEchosounder.h:309
double svFloorDb
The lowest Sv ever reported, dB.
Definition SensorEchosounder.h:305
int beamSamples
The samples across the beam per range bin: the axis, then a ring.
Definition SensorEchosounder.h:302
double bottomThresholdDb
The Sv a bin needs to be detected as the bottom, dB.
Definition SensorEchosounder.h:310
double rayStepSize
The search step of the ray intersection, m.
Definition SensorEchosounder.h:295
unsigned int noiseSeed
The random seed; zero is a perfect instrument.
Definition SensorEchosounder.h:312
double maxRangeDown
The longest slant range searched and binned, m.
Definition SensorEchosounder.h:294
double rangeNoiseStd
The absolute range noise standard deviation, m.
Definition SensorEchosounder.h:298
double binSize
The echogram range bin size, m.
Definition SensorEchosounder.h:304
double pingPeriod
The time between pings, s.
Definition SensorEchosounder.h:293
One Species Concentration field as the acoustic model sees it.
Definition SensorEchosounder.h:327
int handle
The field handle, resolved once in FinalSetup.
Definition SensorEchosounder.h:329
std::string name
The scalar field name.
Definition SensorEchosounder.h:328
double lengthCm
The field's mean length, cm.
Definition SensorEchosounder.h:331
std::string speciesKey
The field's species, a key of the Parameter library.
Definition SensorEchosounder.h:330
std::vector< double > sigmaBsPerKg
sigma_bs per kg at each frequency, m^2/kg.
Definition SensorEchosounder.h:332