„Der allmächtige Herr! Es scheint, als hätte ich gerade Mr. May getötet! ... Aber wie auch immer, wir machen weiter “(C) J. Clarkson
In diesem Artikel werde ich Ihnen erklären, wie Sie Videos (fast Videos) mit Ton durch Wasser mit einem normalen Laptop, einem Stück Draht, zwei 3,5-mm-Buchsen und zwei Hochtöner-Piezo übertragen. Ich werde auch erklären, warum und wie es funktioniert, und eine lustige Geschichte darüber erzählen, wie wir darauf gekommen sind. Und als Kirsche auf einem Kuchen ist dem Artikel ein Artikel über C # mit Quellcodes beigefügt, damit jeder, der interessiert ist, es selbst versuchen kann, weil wissenschaftliche Erkenntnisse überprüfbar sind, nicht wahr?
Wenn der Leser plötzlich etwas tiefer in die Sonarthemen eintauchen möchte, empfehle ich Ihnen, sich mit unseren früheren Veröffentlichungen vertraut zu machen, in denen wir über unsere Projekte so sprechen, dass die Schwierigkeiten bei der Übertragung von Informationen über Wasser deutlich werden:
Unterwasser-GPS von Grund auf neu pro JahrUnterwasser-GPS: FortsetzungNavigation unter Wasser: Peilung - keine Peilung, Sie sind zum Erfolg verurteiltÜber die Wirkung von Cyanobakterien auf die Sprachfunktionen des PräsidentenIm Allgemeinen muss eine einfache Wahrheit gelernt werden: Video durch Wasser in einer signifikanten Entfernung (mindestens Hunderte von Metern) kann nicht mit Akustik übertragen werden. Der Punkt ist das extrem enge verfügbare Frequenzband und die starke Ungleichmäßigkeit der Dämpfung verschiedener Frequenzen mit der Entfernung. Die Pluspunkte sind Rauschen, Mehrwegeausbreitung, Nachhall, Änderung der Schallgeschwindigkeit im Medium aufgrund der Dichte (d. H. Druck, Temperatur und Salzgehalt), der Doppler-Effekt, der übrigens nicht ganz so funktioniert wie bei der Funkkommunikation.
Die Geschwindigkeitsbegrenzungen für die fortschrittlichsten Sonarmodems sind weit davon entfernt, Videos übertragen zu können. Soweit ich weiß, gehört der Datensatz EvoLogics und beträgt 62,5 kbit / s bei einer angegebenen maximalen Entfernung von 300 Metern. Darüber hinaus gehören die Worte über die Unmöglichkeit der Übertragung von Videoklang durch Wasser (in angemessenen Entfernungen) nur Konstantin Georgievich, Gründer und Direktor von EvoLogics.
Als ich ein Forscher am Hydrosvyaz-Forschungsinstitut war, damals völlig bewusstlos, wollte ich große Erfolge,
Siege im Norden und Süden, große Bodenlockerungen (nein, ich will sie immer noch, aber dann war ich überhaupt nicht mit Erfahrung und Wissen belastet und alles schien fast magisch und fabelhaft). In unserem damaligen Team (von dem ein Teil mein echtes ist) haben wir oft von unrealistischen Sonarprojekten geträumt, auf einer
Mülldeponie gestöbert und versucht, alle möglichen Artefakte einer großen alten Zivilisation hintereinander zu verwenden, von denen dieses Forschungsinstitut teilweise versucht, das Tao der Sonarkommunikation zu verstehen .
Das Eintauchen in diese Erinnerungen ruft in mir widersprüchliche Gefühle hervor. Dann schien nichts und niemand konnte uns aufhalten: Wir haben eine chinesische Fräsmaschine vom Direktor für das Prototyping von Produkten ausgeschaltet, normobare Körper aus niederländischen Wasserleitungen Van De Lande zusammengebaut, deren Hersteller sogar einen Brief zu diesem Thema schrieb: „Haben Sie versehentlich überprüft, welche Halten Ihre Rohre dem äußeren Druck stand? “ Sie sammelten Steckbrettmodelle für ihr eigenes Geld in Frühstücksbehältern und gingen heimlich zum Test, um sie heimlich zu testen. Sie sammelten Eisbohrer und Schlitten für Kollegen und Verwandte und kauften sogar ein chinesisches PVC-Boot in Auchan. Wenn ich zurückblicke, spüre ich, wie mein Herz voller Entsetzen, Nostalgie und Angst ist.
Fairerweise ist es erwähnenswert, dass wir die ganze Zeit über große Unterstützung von einigen unserer Führer erhalten haben - in Wort und Tat, und infolgedessen wurden alle unsere Handwerke in OCD (dh experimentelle Entwurfsarbeit und nicht Zwangsstörung) legalisiert, was gleichmäßig war 2013 im internationalen Marine-Salon vorgestellt. Ja, ja, wir fuhren mit unseren Wasserpfeifen zum Salon und malten
StDmitirev in
unserer eigenen Hand in leuchtendem Orange! Hier sind sie in Koffern:

Eines Tages
sprach mein Freund und Kollege
StDmitirev mitten in einem Gespräch über Spektren und Spektrogramme den folgenden Satz aus:
"Aber es würde Spaß machen, ein solches System zu bauen: Der U-Boot sitzt im U-Boot und schaut auf den Monitor, auf dem sich das Spektrogramm reibungslos bewegt, auf dem Buchstaben und Zahlen wie der Finger eines anderen U-Bootes auf das neblige Fenster eines anderen U-Bootes geschrieben sind ."
Alle lachten, entwickelten dieses Thema, es scheint, dass sie noch am selben Tag einen Smiley auf das Spektrogramm zeichneten und hörten, wie es sich anhört. Ich wollte das wirklich auf ein praktisches Aussehen bringen.
Jetzt ist es schwer zu merken (es war 2012). Ich hatte einen funktionierenden Computer mit einer Webcam, verschiedenen Artefaktantennen und einem speziellen „Bucket Sonar Boosting“ (VG-1-P) mit Wasser. Sie nannten ihn einen Schritt nach oben, weil ich allen seinen Vorgesetzten die Arbeit verschiedener Ausrüstungsmodelle darin zeigte, was zu meiner Beförderung zum leitenden Forscher führte.
Ich bin nicht an irgendwelche Verpflichtungen gebunden, die Methode selbst wurde lange Zeit öffentlich veröffentlicht und die Ergebnisse wurden wiederholt auf Konferenzen berichtet.
Ich sage Ihnen also, wie im Geiste - wie man ein Video durch Wasser überträgt:
Wie erzeuge ich ein Signal?
Wir erinnern uns, dass die Idee auf dem „Zeichnen auf einem Spektrogramm“ basiert, dh das übertragene Bild ist das Spektrogramm des Signals. Um ein Signal aus dem Zeitbereich in den Frequenzbereich und umgekehrt umzuwandeln, ist es zweckmäßig, der Kürze halber die Fourier-Transformation oder besser gesagt die schnelle Fourier-Transformation zu verwenden, die als FFT oder häufiger als FFT (Fast Fourier Transform) bezeichnet wird.
Da wir ein Bild (Videobild) in ein Audiosignal umwandeln müssen, das von der Soundkarte eines Computers ausgegeben werden kann, verwenden wir offensichtlich die inverse Transformation IFFT, um es zu erzeugen. Wir werden ein Bild in Spalten ausgeben und ein Signal für eine Spalte wird wie in der folgenden Abbildung erzeugt:
=
Angenommen, die FFT-Fenstergröße ist N und wir haben ein Array der Größe N. Wenn wir es als das Spektrum des Signals betrachten, entspricht sein Nullelement der Nullfrequenz (konstant) und die Zählung mit dem N-1-Index entspricht der Abtastrate der Abtastrate. Es ist notwendig, solche Bildrahmengrößen und FFT-Fenstergrößen so zu wählen, dass einerseits alles irgendwie dem Video ähnelt (das Übertragen eines Rahmens würde eine angemessene Zeit in Anspruch nehmen), und andererseits war das verwendete Frequenzband im Prinzip angemessen und den verfügbaren Geräten angemessen . Wenn wir nun die Helligkeitswerte der Bildspalte (Frame-Spalte) von einer bevorzugten Anzahl (von unten nach oben im Diagramm) eingeben und dann die inverse FFT durchführen, erhält der Ausgang ein Signal, das eine Spalte des Bildes codiert. Jetzt bleibt es uns überlassen, die Signale für die verbleibenden Bildspalten auf die gleiche Weise zu bilden und sie abwechselnd mit einer Soundkarte auszusenden.
Es ist erwähnenswert, dass die FFT am Ausgang eine Reihe komplexer Werte liefert, sodass unser Signal der Realteil ist. Natürlich wird das resultierende Signal in den Spalten auf 16-Bit-Ganzzahlen mit Vorzeichen reduziert (in dieser Form wird normalerweise ein digitales Audiosignal gespeichert) und normalisiert.
Tatsächlich gebe ich zu Beginn des Bildes auch einige Spalten mit maximaler Helligkeit ein. Später auf der Empfängerseite bestimmt dies den Frequenzgang des Transceiverpfads (und des Übertragungskanals), der uns bei Invertierung und leichter Glättung hilft, den empfangenen Rahmen zu verbessern.
Meiner Meinung nach ist es am einfachsten, das Sendergerät mit einem Code zu demonstrieren, hier ist es (Encode-Methode der Encoder-Klasse):
public double[] Encode(Bitmap source) { 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); double[] samples = new double[fftSize * frameSize.Width]; alglib.complex[] slice = new alglib.complex[fftSize]; double maxSlice; int sampleIndex = 0; int colsCount = frameSize.Width; int startRow = startLine; int endRow = startRow + frameSize.Height; for (int x = 0; x < colsCount; x++) { for (int y = startRow; y < endRow; y++) slice[y].x = (frame.GetPixel(x, frameSize.Height - (y - startRow) - 1).R / 255.0) * short.MaxValue; for (int y = 0; y < fftSize; y++) slice[y].x *= randomizerMask[y]; alglib.fftc1dinv(ref slice); maxSlice = double.MinValue; for (int y = 0; y < slice.Length; y++) if (Math.Abs(slice[y].x) > maxSlice) maxSlice = Math.Abs(slice[y].x); for (int i = 0; i < slice.Length; i++) { samples[sampleIndex] = (short)Math.Round(slice[i].x * short.MaxValue / maxSlice); sampleIndex++; } } return samples; }
Der Code gibt natürlich nichts vor und wurde in Eile nur zur Demonstration geschrieben.
Was ist also mit der Übertragungsgeschwindigkeit?
Und wie bewertet man das? Wir haben es geschafft (
vom Bösen nicht vom Bösen), die Intrigen etwa zwei Monate lang aufrechtzuerhalten, und einige unserer hochrangigen Kameraden und Führer haben es geschafft, in ihrer Freizeit ein paar Papiere zu schreiben und sich zu fragen, wie sich eine so verrückte Übertragungsgeschwindigkeit entwickeln könnte.
Wenn beispielsweise die Abtastfrequenz 96 kHz beträgt und wir die FFT-Fenstergröße auf 512 setzen, senden wir 120 x 120 Pixel (8 Bit pro Pixel) an den Sendeeingang. Die Zeit zum Senden eines Bildrahmens beträgt:
120 * 512/96000 = 0,64 SekundenDie Bitrate sollte wie folgt aussehen:
120 x 120 * 8 / 0,64 = 180.000 Bit pro Sekunde!Der Sohn des Regisseurs war damals begeistert - ja, Sie können bereits Internetprotokolle verwenden! Dies ist ein Durchbruch!Wie ich weiter unten zeigen werde, ist es sehr leicht, in ein solches Missverständnis zu geraten. Was ist hier falsch? Immerhin ist alles so einfach und elegant!
Tatsächlich gilt eine solche Berechnung der Geschwindigkeit für dieses Verfahren nicht, so wie sie beispielsweise nicht für ein analoges Fernsehsignal gilt. Wie viele Bits pro Pixel gibt es? =) Und was ist mit dem einfachsten Detektorempfänger? =))
Die beschriebene Übertragungsmethode ist im Wesentlichen
ANALOG und die Konzepte von "Bit" und "Pixel" sind nicht auf sie anwendbar. Im selben Bild können Sie theoretisch nicht 8 Bit pro Pixel Helligkeit aufnehmen, aber 16 und "Geschwindigkeit" verdoppeln sich automatisch.
Es ist Zeit, die ersten Ergebnisse unseres „Durchbruchs“ zu zeigen:

Das Bild oben wurde von uns im Winter 2012 am Pichuga River aufgenommen. Die Übertragungsentfernung betrug 700 Meter. Ja, leider, mein lieber Leser, dies ist überhaupt nicht HD und greift nicht einmal auf den beschämendsten CamRip zurück. Ich erinnere mich nicht, wer das schon war, aber jemand hat sehr genau bemerkt, dass all unsere "Videos" wie das Senden von Signalen für Hilfe von einem sterbenden Planeten sind.
Bemerkenswert ist, dass dies mit einer Ausdehnung als eine Art OFDM bezeichnet werden kann - die Daten werden auf orthogonalen Unterträgern übertragen, was eine gute Beständigkeit gegen tonale und andere schmalbandige Interferenzen bedeutet - in diesem Fall sind einzelne "Linien" des Bildes verzerrt. Im Gegensatz dazu verzerrt Impulsrauschen eine oder mehrere Spalten. Die charakteristische "Streifenbildung" der Bilder wird durch das sogenannte verursacht frequenzselektives Fading aufgrund von Mehrwegeausbreitung, aber ich werde ein anderes Mal darüber sprechen.
Wie ist der Empfänger angeordnet?
Ich werde sofort reservieren, dass zwei Stunden lange Stücke (solche runden) mit einem Anschluss für eine daran gelötete Soundkarte ausreichen, um diese Methode in einem Eimer oder sogar in einem kleinen Pool auszuprobieren. Für den Sender können Sie ein ziemlich langes (2-3-4-5 Meter) und ungeschirmtes Kabel verwenden, um das piezoelektrische Element mit Zapon-Lack oder einer kleinen Schicht Dichtmittel abzudichten - genug für mehrere Male. Die resultierende Sonarantenne (nicht, na ja, was?) Wird in die Kopfhörerbuchse eingesteckt.
Das Foto unten zeigt verschiedene Stücke, die zum Zeitpunkt des Schreibens zur Hand waren. Alle gezeigten piezoelektrischen Elemente eignen sich gut zum „Ausprobieren“, und normalerweise befindet sich in jeder
Müllkippe ein Radiogeschäft. Pyatak hat keinen piezoelektrischen Effekt und ist im Bild für die Skalierung vorhanden.

Für den Empfänger ist es besser, ein abgeschirmtes Mikrofonkabel mit demselben Stecker und einen Piezo zu verwenden, der am Ende mit Dichtmittel oder Lack verschmiert ist. Wir stecken diese Antenne in die Mikrofonbuchse.
Für Experimente an einem Teich ist es besser, eine Art Piezo-Ring als Sender zu nehmen und ihn mit einem verstärkten zu versorgen (ein Verstärker an einem TDA2030 mit einem korrekt gewickelten Transformator hält in einem guten Teich mehrere hundert Meter
oder es können weitere 5 Windungen gewickelt werden). Für den Empfänger sind in diesem Fall auch ein Vorverstärker und vorzugsweise ein Bandpassfilter erforderlich. Wenn die Leser mehr darüber erfahren möchten, teilen Sie uns dies in den Kommentaren mit. Wir werden versuchen, einen Artikel über die Entwicklung von Leistungsverstärkern, Vorverstärkern und Antennen für die Sonarkommunikation zu verfassen.
Also zurück zum Empfänger, genauer zu seinem Software-Teil
Das Wichtigste bei der Kommunikation ist die Synchronisation und Bestimmung des Vorhandenseins eines Nutzsignals. In unserem Beispiel wird die Erkennung durch die Energie im Band durchgeführt: Stellen, an denen sie stark ansteigt (Anfang des Rahmens) und an denen sie stark abfällt (Ende des Rahmens), werden unter der Bedingung bestimmt, dass von vorne bis unten mindestens die Dauer des Rahmens vorhanden sein sollte.
Bei aller Einfachheit funktioniert es überraschend gut.
Daten von der Soundkarte werden von FFTSize-Samples gesammelt, FFT wird sofort auf ihnen ausgeführt und sie werden als separate „Slices“ gespeichert. Sie warten auf den Moment, in dem sie von der Suchprozedur verarbeitet werden. Hier ist ihr Code (Suchmethode in der Receiver-Klasse):
private void Search() { int sliceIndex = 0; int frameWidth = encoder.FrameSize.Width; int minSlicesToSearch = Convert.ToInt32((frameWidth + 5) * 2); int sliceSize = encoder.FFTSize; double weight; int lastRisePosition = 0; int prevRisePosition = 0; while ((slices.Count > minSlicesToSearch) && (sliceIndex < slices.Count)) { weight = 0.0; for (int i = 0; i < sliceSize; i++) weight += Math.Abs(slices[sliceIndex][i]); double ratio = weight / previousWeight; if ((ratio >= risePeekRatio) && (sliceIndex - prevRisePosition > frameWidth)) { prevRisePosition = lastRisePosition; lastRisePosition = sliceIndex; if (lastRisePosition + (frameWidth + 5) < slices.Count) { double[][] samples = new double[frameWidth + 5][]; for (int i = 0; i < frameWidth + 5; i++) { samples[i] = new double[sliceSize]; Array.Copy(slices[lastRisePosition + i], samples[i], sliceSize); } slices.RemoveRange(0, sliceIndex); lastRisePosition = 0; if (FrameReceived != null) FrameReceived(this, new FrameReceivedEventArgs(encoder.DecodeEx(samples, 5))); lastRisePosition = sliceIndex; } } sliceIndex++; previousWeight = weight; } Interlocked.Decrement(ref isSearching); }
Und hier ist ein Code, der für die Dekodierung des Bildes verantwortlich ist (Encoder.DecodeEx):
public Bitmap Decode(double[] samples, int measureCols) { int colCount = samples.Length / fftSize; if (colCount == frameSize.Width + measureCols) { int rowCount = frameSize.Height; Bitmap temp = new Bitmap(colCount, rowCount); double[] slice = new double[fftSize]; alglib.complex[] sliceC = new alglib.complex[fftSize]; int samplesCount = 0; byte component; int decodeStart = startLine; int decodeEnd = startLine + rowCount; double maxSlice; for (int x = 0; x < colCount; x++) { for (int y = 0; y < fftSize; y++) { slice[y] = samples[samplesCount]; samplesCount++; } alglib.fftr1d(slice, out sliceC); maxSlice = double.MinValue; for (int y = decodeStart; y < decodeEnd; y++) if (alglib.math.abscomplex(sliceC[y].x) > maxSlice) maxSlice = alglib.math.abscomplex(sliceC[y].x); int offset = temp.Height + decodeStart - 1; for (int y = decodeStart; y < decodeEnd; y++) { component = (byte)(255.0 * alglib.math.abscomplex(sliceC[y].x) / maxSlice); temp.SetPixel(x, offset - y, Color.FromArgb(component, component, component)); } } return temp; } else { throw new ApplicationException("Specified array length error"); } }
Und jetzt schlage ich vor, die Ergebnisse von Experimenten zur Übertragung von "Video" zu betrachten, die zu unterschiedlichen Zeiten in verschiedenen Reservoirs durchgeführt wurden.
Beide Bilder (unten) wurden 2013 im internationalen Marine-Salon in St. Petersburg an unserem (damaligen) Stand durch zwei Laptops und ein Aquarium aufgenommen.
Es ist nicht möglich zu erkennen, was auf dem Abzeichen steht


Und hier sind zwei „Videos“, die von uns in einer der Buchten des Ladogasees in Karelien aufgenommen wurden. Sie sind eine Art Aufzeichnung für diese Methode (wir haben es einfach nie mehr versucht und sind es wahrscheinlich nicht) - das erste wurde in einer Entfernung von 500 und das zweite in einer Entfernung von 1000 Metern aufgenommen ::
Videoübertragung durch Wasser, Entfernung 500 m (Datei 8,7 mb)
Da das "Video" in Echtzeit mit einer Webcam aufgenommen wurde, fielen verschiedene seltsame Dinge in den Rahmen. Es wird sehr interessant sein, wenn jemand errät und in einen Kommentar schreibt, was im Hintergrund des letzten „Videos“ steht.
Zur Unterstützung der Tatsache, dass die Methode vor langer Zeit veröffentlicht wurde -
unser Artikel bereits für 2013
Ich habe die wunderbare
AForge- Bibliothek verwendet,
um Webcam-Bilder aufzunehmen .
Komplexe
Zahlen- und FFT-Funktionen werden aus der hervorragenden
AlgLib- Bibliothek verwendet.
Und wie ich versprochen habe, ist das gesamte Projekt in C # (VS2012) dem Artikel als Material für die "Heimarbeit" beigefügt. Der Einfachheit halber sind das
Projekt und die
Binärdateien getrennt.
Die Demo bietet die Möglichkeit, das belegte Frequenzband zu ändern (zu verschieben) sowie die Gammakorrektur des Ausgangsrahmens (alles kann in Echtzeit geändert werden).
PS
Ich habe C # schon lange nicht mehr gelernt und es ist sehr schwierig, die Zeit im Arbeitsplan zu finden. Deshalb entschuldige ich mich im Voraus für die Verwirrung und Eile des Codes.
PPS
Ich befestige kein Stück Draht, zwei Buchsen und zwei Teile am Artikel - nicht genug für alle.
Errata und Anhang
- In einigen Soundkarten am Eingang befindet sich ein Tiefpassfilter, der auf tragische Weise alles über ~ 15 kHz schneidet (warum ???).
- Standardmäßig arbeitet das Demo-Projekt mit einer Abtastfrequenz von 96 kHz, aber nicht alle modernen Soundkarten unterstützen dies (Warum ???). Wenn das Gerät nicht 96 kHz kann, müssen Sie in den Einstellungen 48 kHz einstellen. Wenn nicht, wird 44100 sicherlich überall unterstützt, die Übertragungsdauer eines Frames ist jedoch entsprechend länger.
Hier ist eine Liste von Laptops und Soundkarten, die als junge Sonarausrüstung gelten können:
- Lenovo Ideapad Y510P mit JBL-Sound
- Asus n55s
- Asus K501U
- externe Soundkarte Sound Blaster X-Fi Surround 5.1 (Modell Nr. SB 1095)