So sehen Sie Nachhall oder Videoübertragung durch Ton durch Wasser - 2

Hallo Schatz!



Heute werden wir das Bild wieder mit Ultraschall durch das Wasser übertragen: Wir werden buchstäblich Nachhall und Echo sehen und sogar, wie sie sich je nach den Bedingungen ändern. Alles, was ich Ihnen sagen werde, ist einfach. Es ist interessant, es selbst zu wiederholen und kann von fast jedem durchgeführt werden.

Wenn durch diese Worte etwas in deiner Seele flattert, willkommen bei Kat, im dunklen Wasser unseres Teiches!




"Der beste Rest ist, bekannte Wahrheiten zu interpretieren." (C) ABS, Mittag, XXII Jahrhundert


Vorspiel


Die Grundregel des Clubs der Zeugen der Hydroakustik lautet, dass Videos mit Hydroakustik in einer mehr oder weniger signifikanten Entfernung (mehr als einige Meter) im mittleren Gewässer nicht übertragen werden können und immer unmöglich sein werden.
Dafür gibt es schwerwiegende Gründe - einen Kommunikationskanal mit einer sehr geringen Bandbreite, einer geringen Signalausbreitungsgeschwindigkeit (in Wasser nur 1.500 m / s) und einer hohen Fehlerwahrscheinlichkeit. Das verfügbare Frequenzband beträgt nur einige zehn Kilohertz.
Dies ist jedoch noch nicht alles - wenn sich relativ gesehen ein Signal mit Frequenzen in der Größenordnung von 10 kHz in einer Entfernung von etwa 8 bis 10 km im Wasser ausbreitet, dann sind es bei einer Frequenz von 20 kHz bereits 3 bis 5 km, und je höher die Frequenz, desto stärker die Dämpfung . Beispielsweise arbeiten unsere kleinsten uWAVE- Modems der Welt im 20-30-kHz-Band und übertragen Daten mit einer Geschwindigkeit von 78 Bit / s pro 1000 Meter und RedLINE mit einem Band von 5-15 bis 8000 Metern. Der Rekord unter den kommerziellen Geräten gehört EvoLogics - 68 kBit pro 300 Meter.
Die Physik kann leider nicht getäuscht werden und es ist unmöglich, ihr zuzustimmen - sie kann entweder sehr langsam und geräuschunempfindlich oder schnell, aber über kurze Entfernungen übertragen werden.
In einigen Fällen ist es jedoch möglich, „einige Ecken abzuschneiden“, wobei die Ecken, die wir dieses Mal abschneiden, niedriger sind.

Was werden wir heute tun und was wird dafür benötigt?


In früheren Artikeln haben wir bereits „Video“ mit Ton durch Wasser übertragen . Ich erinnere Sie daran, dass dort der Rahmen „auf das Spektrum gezeichnet“ wurde, dh das Spektrum oder vielmehr das Spektrogramm des Signals war ein Bild.
Später haben wir einfache hydroakustische Antennen aus Müll hergestellt und das einfachste hydroakustische Modem hergestellt . Dort haben wir auch einen Vorverstärker für die Antenne hergestellt (hier liegt noch das Design der Leiterplatte zur Eigenproduktion durch LUT-Ohm).

Wir dachten uns, wie sonst können Sie versuchen, das Bild so zu vermitteln, dass selbst ein Kindergartenschüler es herausfinden kann, und wie es uns scheint, haben sie einen noch einfacheren Weg gefunden als zuvor.

Um es zusammenzufassen, erstellen Sie eine Liste dessen, was wir brauchen:

- ein Paar Sonarantennen von Tortenpflückern
- Vorverstärker von LUT
- Quellcode des C # -Projekts
- ein Paar Bleibatterien mit 12 Volt
- ein Verstärker auf TDA, ich nahm einen für nur 50 Rubel auf Ali

Ein bisschen Theorie


Denken Sie daran, dass unser Sonarmodem auf einem einfachen Tondetektor basiert, dessen Frequenz viermal niedriger ist als die Abtastfrequenz. Erinnern Sie sich kurz daran, wie es funktioniert.


Das Bild zeigt zwei Schwingungen, die auf Pi / 2 relativ zueinander verschoben sind, dh die Sinus- und die Cosinusphase. Und wenn die Frequenz genau viermal niedriger als die Abtastfrequenz ist, fallen nur vier Abtastwerte auf die Periode.
Ein aufmerksamer Habuchitel bemerkte sicherlich, dass beide Signale auf Pi / 4 verschoben sind. Bei einer solchen Verschiebung nimmt das Signal nur zwei Werte an: √2 / 2 und -√2 / 2.
Und bestimmte Werte sind nicht einmal wichtig, es ist wichtig, dass Sie nur die Zeichen "+" und "-" verwenden können.

Jetzt können wir die Sinusphase als Folge von Zeichen "+" "+" "-" "-" und die Cosinusphase als "+" "-" "-" "+" darstellen.

Wiederholen Sie unter dem Spoiler den Detektor:
Wenn sich das Eingangssignal im sn-Puffer befindet, haben wir zwei Ringmittelungspuffer für die Sinus- und Cosinusphase - bs und bc der Größe N. Sie haben gemeinsame Kopf- und Schwanzzeiger - bH und bT. Zum anfänglichen Zeitpunkt ist bH = N-1, bT = 0. Mittelungszykluszähler C = 0.
Wir nehmen 4 Samples aus dem Eingabepuffer und fügen sie entsprechend den Zeichenfolgen hinzu.

a = sn(i)
bs(bH) = a
bc(bH) = a
s1 = s1 + a - bs(bT)
s2 = s2 + a - bc(bT)
bH = (bH + 1) % N
bT = (bT + 1) % N

a = sn(i+1)
bs(bH) = a
bc(bH) = -a
s1 = s1 + a - bs(bT)
s2 = s2 - a - bc(bT)
bH = (bH + 1) % N
bT = (bT + 1) % N

a = sn(i+2)
bs(bH) = -a
bc(bH) = -a
s1 = s1 - a - bs(bT)
s2 = s2 - a - bc(bT)
bH = (bH + 1) % N
bT = (bT + 1) % N

a = sn(i+3)
bs(bH) = -a
bc(bH) = a
s1 = s1 - a - bs(bT)
s2 = s2 + a - bc(bT)
bH = (bH + 1) % N
bT = (bT + 1) % N


Nach jeder Verarbeitung von vier Abtastwerten überprüfen wir den Zähler der Mittelungszyklen und berechnen, wenn er N überschritten hat, die Amplitude cA des Trägers:

if ++cycle >= N
cA = sqrt(s1 * s1 + s2 * s2)
cycle = 0
end



Wir nehmen diese Methode als Grundlage, sie wird für die „Synchronisation“ verantwortlich sein.
Nun wollen wir sehen, wie das Bild codiert ist. Ich schlage vor, die Amplitudenmanipulation zu verwenden . Manipulation ist, wenn ein Signal in gleiche Segmente unterteilt wird, die als Chips oder Symbole bezeichnet werden, und ein variabler Parameter (in unserem Fall die Amplitude) entlang der Länge des Chips gespeichert wird.
Wenn wir beispielsweise die Amplitude im Bereich von 0 bis 32767 (16-Bit-Abtastwerte) variieren können und 255 Werte der Helligkeit der Pixel übertragen müssen, ändert sich die Amplitude des Chips pro Änderungseinheit der Helligkeit des Pixels auf 32768/255 = 128.
Ein weiterer wichtiger Parameter ist die Länge des Chips. Wir beginnen mit einer Trägerperiode - in unserem Fall vier Samples.
Das Bild wird also Pixel für Pixel übertragen, jedes Pixel dauert 4 Abtastungen, und die Amplitude für diese Periode beträgt b [x, y] * 128, wobei b [x, y] der Helligkeitswert des Pixels mit x- und y-Koordinaten im Bild b ist.

Lassen Sie uns die Übertragungsgeschwindigkeit abschätzen.
Im Beispiel habe ich eine Bildgröße von 120 x 120 Pixel verwendet. Dies bedeutet, dass wir zum Übertragen eines Frames benötigen

120 x 120 x 4 = 57600 Proben,

Wenn die Abtastfrequenz 96 kHz beträgt, dauert die Übertragung eines Frames einige Zeit:

57600/96000 = 0,6 Sekunden

Offensichtlich brauchen wir eine Art Pause, ein bestimmtes Schutzintervall, damit der Detektor den Beginn des nächsten Frames bestimmen kann. Nehmen wir aus humanen Gründen an, dass 0,1 Sekunden für uns ausreichen, in denen alle Echos aussterben (eigentlich nicht). Am Ende stellt sich dann die Übertragungsrate heraus:

1 / (0,6 + 0,1) = 1,428 Bilder pro Sekunde.

Es ist sehr leicht, hier einen Fehler zu machen und zu versuchen, die Geschwindigkeit in Bit pro Sekunde zu berechnen. Sehen Sie, wie unglaublich die Übertragungsgeschwindigkeit ist:

120 * 120 * 8 / 1,428 = 80 627 bps

Aber was passiert, wenn ich keine 8-Bit-Pixel, sondern 16-Bit-Pixel habe?

120 * 120 * 16 / 1,428 = 161344 bps

Der Haken dabei ist, dass diese Übertragungsmethode wiederum nicht als digital bezeichnet werden kann und das Konzept der Bitrate für sie nicht vollständig gültig ist.
Versuchen Sie, die Bitrate für ein analoges Fernsehsignal zu berechnen. Und für den Detektorempfänger? :) :)

So sieht beispielsweise ein Teil des Signals aus und überträgt die Helligkeit von 10 Pixeln, deren Werte sich abwechselnd ändern: 1 2 1 2 1 2 1 2 1 2


Nun wollen wir im Beispiel sehen, wie das funktioniert. Encode- und Decode-Methoden befinden sich in der Encoder- Klasse und sind für die Modulation und Demodulation des Bildes verantwortlich:

 public double[] Encode(Bitmap source, double carrier, int pSize, int interframePauseMs) { Bitmap frame; if (source.PixelFormat != System.Drawing.Imaging.PixelFormat.Format8bppIndexed) frame = Grayscale.CommonAlgorithms.RMY.Apply(source); else frame = source; if (!frame.Size.Equals(frameSize)) frame = resizer.Apply(frame); int cols = frameSize.Width; int rows = frameSize.Height; int col = 0; int row = 0; double delta = Math.PI * 2 * carrier / sampleRate; double alpha = 0; double phase = 0; double pxAmplitude = 0; double chipLimit = Math.PI * 2 * chipSize; double pLimit = Math.PI * 2; List<double> samples = new List<double>(); bool isFinished = false; for (int i = 0; i < pSize; i++) { alpha = Math.Sin(phase); phase += delta; if (phase >= pLimit) { phase -= pLimit; } samples.Add(alpha * short.MaxValue); } while (!isFinished) { alpha = Math.Sin(phase); phase += delta; if (phase >= chipLimit) { phase -= chipLimit; pxAmplitude = (((double)frame.GetPixel(col, row).R) / 255.0) * short.MaxValue; if (++col >= cols) { if (++row >= rows) isFinished = true; else col = 0; } } samples.Add(alpha * pxAmplitude); } if (interframePauseMs > 0) { samples.AddRange(new double[(int)((((double)interframePauseMs) / 1000.0) * (double)sampleRate)]); } return samples.ToArray(); } 


Aus dem Code ist ersichtlich, dass vor dem Modulieren des Bildes dem Ausgangssignal ein aus reinem Ton (pSize-Samples) bestehendes Synchronisationspräfix hinzugefügt wird - dies ist erforderlich, damit auf der Empfangsseite eine Synchronisation vor dem Bild selbst und im Allgemeinen unter ungünstigen Bedingungen stattfinden kann.
Die Decodierungsmethode lautet wie folgt:

 public Bitmap Decode(double[] samples, double carrier, int pSize) { int cols = frameSize.Width; int rows = frameSize.Height; int col = 0; int row = 0; Bitmap result = new Bitmap(cols, rows); double delta = Math.PI * 2 * carrier / sampleRate; double alpha = 0; double phase = 0; double chipLimit = Math.PI * 2 * chipSize; double chipAmplitude = 0; double maxAmplitude = WaveUtils.GetMaxAmplitude(samples); double pxMax = -maxAmplitude; double pxMin = maxAmplitude; double smp; for (int i = pSize; (i < samples.Length) && (row < rows); i++) { alpha = Math.Sin(phase); phase += delta; if (phase >= chipLimit) { phase -= chipLimit; chipAmplitude = (Math.Max(Math.Abs(pxMax), Math.Abs(pxMin)) / maxAmplitude); pxMin = maxAmplitude; pxMax = -maxAmplitude; var gs = Convert.ToByte(chipAmplitude * 255); result.SetPixel(col, row, Color.FromArgb(255, gs, gs, gs)); if (++col >= cols) { col = 0; row++; } } else { smp = samples[i] * alpha; if (smp > pxMax) pxMax = smp; if (smp < pxMin) pxMin = smp; } } return result; } 


Es ist ersichtlich, dass beide Methoden nicht an eine bestimmte Frequenz gebunden sind und mit einem anderen Detektor verwendet werden können.

Die Signalsuche selbst (Erkennung, Synchronisation) erfolgt ebenfalls wie bei unserem einfachsten hydroakustischen Modem , mit dem einzigen Unterschied, dass ich sie zur Änderung in eine separate Klasse FsBy4CarrierDetector eingeordnet habe .
Alle unkomplizierte Magie geschieht in der bool ProcessSample-Methode (kurz a)

 public bool ProcessSample(short a) { bool result = false; if (smpCount == 0) { ring1[ringHead] = a; ring2[ringHead] = a; s1 += a - ring1[ringTail]; s2 += a - ring2[ringTail]; } else if (smpCount == 1) { ring1[ringHead] = a; ring2[ringHead] = -a; s1 += a - ring1[ringTail]; s2 += - a - ring2[ringTail]; } else if (smpCount == 2) { ring1[ringHead] = -a; ring2[ringHead] = -a; s1 += -a - ring1[ringTail]; s2 += -a - ring2[ringTail]; } else if (smpCount == 3) { ring1[ringHead] = -a; ring2[ringHead] = a; s1 += -a - ring1[ringTail]; s2 += a - ring2[ringTail]; } ringHead = (ringHead + 1) % ringSize; ringTail = (ringTail + 1) % ringSize; if (++smpCount >= 4) { smpCount = 0; if (++cycle >= ringSize) { s = Math.Sqrt(s1 * s1 + s2 * s2) / ringSize; cycle = 0; result = (s - sPrev) >= Threshold; sPrev = s; } } return result; } 


Es wird bei jeder eingehenden Probe aufgerufen und gibt im Falle der Trägererkennung true zurück.

Da der Detektor alles andere als perfekt ist und leicht in der Mitte der Linie synchronisiert werden kann, habe ich einen speziellen Schieberegler hinzugefügt, mit dem Sie eine genauere Synchronisation erzielen können.

Nachdem wir nun kurz untersucht haben, wie dies alles funktioniert, gehen wir zum köstlichsten Teil über: Was kann daraus gewonnen werden?

Ein bisschen Übung


Lassen Sie uns zunächst überprüfen, wie alles ohne Sonarkanal funktioniert - indem Sie einfach die Empfangs- und Sendeantennen aneinander anschließen.
Erstens ist das Bild größer (240x120), damit zumindest etwas erkannt werden kann:


Und dann schnell, damit es mehr Leben gibt wie ein Video:


Es scheint nicht schlecht zu sein? Aber beeilen Sie sich nicht zu Schlussfolgerungen und gehen Sie zum Schwimmbad:


Und hier werden wir, wie ich im Titel versprochen habe, ein Echo mit eigenen Augen sehen:


Wie gefällt dir das, Elon Musk? Magst du HD? Warum ist das so?
Und alles ist sehr einfach - das Echo sind im Wesentlichen die verzögerten Kopien des Originalsignals, die bekanntermaßen am Empfangspunkt stören, sich in einer anderen Phase falten und ein solches Bild ergeben. Da wir das Bild übertragen, erhalten wir am Ende viele, viele Bilder, die sich mit unterschiedlichen Amplituden überlagern. All dies führt letztendlich zu Unschärfe und Reproduktion.

Lassen Sie uns im Rückblick alles auf dem großen Bild des Modells überprüfen. Ich habe ein zufälliges Foto gemacht:


Ich habe es moduliert, dann ein Echo und ein bisschen Rauschen hinzugefügt, dann wurde es dekodiert und ja - das Ergebnis ähnelt dem, was wir im Pool bekommen haben:


Im Prinzip ist es möglich, Entfaltung durchzuführen und Reflexionen zu subtrahieren, aber es sind Menschen von außerhalb unseres Gebiets, die diesen Punkt für eine unabhängige Arbeit verlassen.

Übrigens funktioniert die vorherige Methode im Pool etwas besser, aber auch schlecht - bei Breitbandsignalen führen Multipath und Reverb zu frequenzselektivem Fading, das im Bild (im Spektrum gelesen) wie schwarze und weiße Streifen aussieht - wenn das Signal gegenphasig ist. und wo es sich in der Phase entwickelt hat (tatsächlich gibt es immer noch eine Reihe von Zwischenoptionen):


Im April nutzten wir den Moment und gingen mit einem Steckbrettmodell zum Teich und verwöhnten uns dort auch:




Das Ergebnis unterscheidet sich nicht wesentlich von den im Pool erzielten Ergebnissen:




Und sofort zum Vergleich die vorherige Methode:


Und hier sind die GIF-Animationen, die aus den gespeicherten Frames gesammelt wurden, Methode 1:


Und Methode 2, die wir in diesem Artikel diskutieren:


Abschließend


Wie versprochen haben wir gezeigt, wie Echo und Hall buchstäblich aussehen, Zeit mit Nutzen verbracht und etwas mit unseren Händen gemacht.

In dieser Form ist die Methode natürlich in der Praxis nicht anwendbar, aber die Arbeit damit ist für Anfänger sehr nützlich.

Im Allgemeinen haben wir in einem flachen Teich nachgesehen, wo die Bedingungen sehr ungünstig sind, und es wäre cool, wenn jemand unsere Experimente in anderen Stauseen wiederholen und sicherlich über ihre Ergebnisse berichten würde.

Wenn der Leser es nur versuchen möchte (auch in der Luft mit Mikrofon und Lautsprechern), dann sind hier die Links zu Veröffentlichungen:
Methode 1
Methode 2 (aus diesem Artikel)

PS

Wir freuen uns sehr auf das Feedback der Leser, da es sehr wichtig ist zu verstehen, dass Sie etwas vergeblich tun (oder vergeblich, und dann sollte dies sofort gestoppt werden).

PS / 2

Ich werde gleich eine häufig gestellte Frage beantworten: Für Fische und andere Meereslebewesen in solchen Kindereinrichtungen ist dies alles nur unbemerkt.

Source: https://habr.com/ru/post/de453678/


All Articles