Folgende Ausgangssituation:
Ich habe Messdaten aus einer Anlage, die aus verschiedenen Messgeräten
stammen, in einer gemeinsamen CSV-Datei.
Die erste Spalte ist immer ein Zeitstempel. Die Messungen aus den
verschiedenen Quellen haben nicht die gleiche Abtastrate, und der
zeitliche Abstand zwischen den Messungen variiert leicht (Jitter). Es
ist aber sichergestellt, dass alle Messgeräte die gleiche Zeitbasis
haben und die Zeitstempel in der Datei aufsteigend sortiert sind.
Beispiel mit zwei Messgeräten mit 5 Hz und 2 Hz Abtastrate:
1
001.002, messgerät1, 22.5, 22.7, 22.3, 22.0
2
001.202, messgerät1, 22.5, 22.7, 22.4, 22.0
3
001.369, messgerät2, 1020.0, 560.0, 552.7
4
001.401, messgerät1, 22.6, 22.7, 22.4, 22.1
5
001.603, messgerät1, 22.6, 22.7, 22.5, 22.1
6
001.801, messgerät1, 22.5, 22.7, 22.5, 22.2
7
001.872, messgerät2, 1020.1, 559.9, 578.9
Ich würde die Messdaten in meinem Programm gerne "abspielen", d.h. die
gemessenen Werte auf verschiedenen virtuellen Instrumenten darstellen,
so wie man es gesehen hätte, wenn man in Echtzeit vor der Anlage
gestanden hätte.
Ich muss also die Messwerte aus der Datei auslesen und an die
Instrumente liefern, dabei aber natürlich irgendwie "oversampeln". Denn
um die nachgebildeten Analoginstrumente für das menschliche Auge
kontinuierlich bewegen zu lassen, brauche ich ca. 20 Hz Wiederholrate.
Meine Idee wäre nun, die Bildschirmausgabe über einen Timer alle 50 ms
auszulösen. Aber mir fehlt noch ein Ansatz zur Interpolation der
Messdaten, besonders bei den unterschiedlichen Abtastraten, mit denen
die einzelnen Parameter eingehen.
Gibt es da schon Algorithmen für, die ich verwenden kann?
Gerhard schrieb:> Beispiel mit zwei Messgeräten mit 5 Hz und 2 Hz Abtastrate:> 001.002, messgerät1, 22.5, 22.7, 22.3, 22.0> 001.202, messgerät1, 22.5, 22.7, 22.4, 22.0> 001.369, messgerät2, 1020.0, 560.0, 552.7
Versteh ich jetzt zuerst mal nicht:
Wie kommst Du zu einem Messzeitpunkt an mehrere Messwerte?
Normal gehört zu einem Zeitpunkt und einem Messgerät 1 Messwert.
Oder werden mit jeweils einem Messgerät mehrere Parameter gemessen?
Gerhard schrieb:> Ich würde die Messdaten in meinem Programm gerne "abspielen", d.h. die> gemessenen Werte auf verschiedenen virtuellen Instrumenten darstellen,> so wie man es gesehen hätte, wenn man in Echtzeit vor der Anlage> gestanden hätte.
Und wie spielst Du ab und genau wohin?
Nur ein File irgendwohin, über seriell, über USB über was?
Was sind das für virtuelle Instrumente und was brauchen die für
Parameter Parameter?
Hast Du Programmierkenntnisse, wenn ja welche.
Du lässt uns arg im Dunklen.
> Oder werden mit jeweils einem Messgerät mehrere Parameter gemessen?
So ist es. Es handelt sich um USB-Datenlogger. Der eine zeichnet
beispielsweise verschiedene Temperaturen auf, der andere Drücke.
> Und wie spielst Du ab und genau wohin?
Ich möchte die Datei mit den Messdaten wiedergeben, so dass die
Geschwindigkeit die gleiche ist wie bei der Aufzeichnung. Die Wiedergabe
soll eine Software übernehmen, die die Datei einliest und dann auf dem
Bildschirm Instrumente darstellt wie Thermometer und Manometer etc.
Es handelt sich um einen Prüfstand für Triebwerke. Das Ziel ist, dass zu
Ausbildungszwecken ein realer Testlauf mit Original-Daten auf dem
Monitor dargestellt werden soll. Im Prinzip wie eine Art Flugsimulator,
der einen gespeicherten Flug abspielt.
> Was sind das für virtuelle Instrumente und was brauchen die für> Parameter Parameter?
Es sind kleine Code-Schnipsel, die analoge Rundinstrumente nachbilden.
Sie haben alle eine update(float value)-Funktion, mittels derer sie sich
auf dem Bildschirm neu zeichnen.
> Hast Du Programmierkenntnisse, wenn ja welche.
C und C++. Die Software wird in C++ auf einem Linux-System entwickelt
und benutzt Qt als GUI.
> Du lässt uns arg im Dunklen.
Sorry - manchmal ist es nicht leicht, sich in den Informationsbedarf
eines anderen hineinzuversetzen
001.002, messgerät1, 22.5, 22.7, 22.3, 22.0
001.202, messgerät1, 22.5, 22.7, 22.4, 22.0
001.369, messgerät2, 1020.0, 560.0, 552.7
001.401, messgerät1, 22.6, 22.7, 22.4, 22.1
001.603, messgerät1, 22.6, 22.7, 22.5, 22.1
Da würde ich einen Timer nehmen, den auf die Startzeit - kleinste
Zeiteinheit setzen.
Startzeit = 001.002 - .001
Jetzt Zeit (Zeit1) der ersten Messzeile auswerten.
Timer starten.
Wenn Timer = Zeit1 dann Werte der Zeile 1 an Instrumente schicken.
Jetzt Zeit (Zeit2) der ersten Messzeile auswerten.
Wenn Timer = Zeit2 dann Werte der Zeile 2 an Instrumente schicken.
usw.
Damit hast Du genau das was Du möchtest. Aber vie Wege führen nach Rom.
Bisher verstehe ich das Problem nicht wirklich. Jeder Wert hat also eine
eigene Anzeige ? Messgerät 1 und 2 werden nicht kombiniert oder
ähnliches ?
Was spricht dann gegen eine lineare Interpolation ? Da du eh keine Daten
hast zwischen den Messzeitpunkten kannst du linear Interpolieren. Egal
wie du die Zwischenschritte berechnest, genau wird es nie sein.
Oder sehe ich irgendwas nicht, was Komplexität hier reinbringt ?
>> Timer starten.> Wenn Timer = Zeit1 dann Werte der Zeile 1 an Instrumente schicken.> Jetzt Zeit (Zeit2) der ersten Messzeile auswerten.> Wenn Timer = Zeit2 dann Werte der Zeile 2 an Instrumente schicken.> usw.>> Damit hast Du genau das was Du möchtest. Aber vie Wege führen nach Rom.
Nein, es macht nicht das was er will. Es geht um Interpolation (also die
Werte ZWISCHEN den Messwerten). Wenn du nur während der Messzeitpunkte
updatest, bekommst du eine zitternde unsaubere Anzeige.
Gerhard schrieb:> Meine Idee wäre nun, die Bildschirmausgabe über einen Timer> alle 50 ms auszulösen.
Ja, logisch.
> Aber mir fehlt noch ein Ansatz zur Interpolation der> Messdaten, besonders bei den unterschiedlichen Abtastraten,> mit denen die einzelnen Parameter eingehen.
Ist kein grundsätzliches Problem; siehe unten.
> Gibt es da schon Algorithmen für, die ich verwenden kann?
Algorithmen oder Programme? :)
Also, aus meiner Sicht hast Du drei gut unterscheidbare
Teilprobleme:
1) Die hinreichend schnelle und gleichmäßige Bereitstellung
der Bildschirmdaten,
2) das Anpassen der Abtastrate der einzelnen Kanäle,
3) die eigentliche Interpolation.
Teilproblem 1) würde ich in Form einer Warteschlage, vielleicht
als Ringpuffer, lösen. Die Elemente der Warteschlange sind
komplette Datensätze mit je einem Abtastwert für jeden Kanal.
Durch den Timer gesteuert werden die Datenblöcke also nur
ausgelesen und der Bildschirm aktualisiert.
Teilproblem 2) erledigt die Routine, die den Ringpuffer wieder
auffüllt. Wenn der Füllstand einen gewissen Mindestwert unter-
schreitet, muss die Auffüll-Routine gestartet werden. Diese
erzeugt zunächst eine bestimmte Anzahl leerer Datenblöcke und
füllt diese anschließend Kanal für Kanal mit Daten. Wenn der
Puffer wieder voll ist, ist Freizeit.
Für das kanalweise Auffüllen ist sicherlich wiederum eine
Warteschlange je Kanal sinnvoll. Es sind also - eigentlich
hätte ich das wissen müssen - in Wahrheit VIER Teilprobleme;
die erste Aktion der Puffer-Auffüll-Routine besteht somit darin,
das Input-File zu lesen und die Daten auf die einzelnen Kanäle
aufzuteilen. Je nach Abtastrate fallen dabei pro Kanal mehr oder
weniger Daten an.
Anschließend wird Kanal für Kanal interpoliert. Am Schluss werden
die Pointer/Indizes im Ringpuffer entsprechend angepasst.
Teilproblem 3) ist die Interpolation im mathematischen Sinne.
Da kann man sich natürlich mit Bezier-Kurven und Hermite-
Interpolation austoben; es wird aber empfehlenswert sein,
zunächst die Bälle flach zu halten und einfach linear zwischen
den Stützstellen zu interpolieren. Wenn sich dabei Mängel
zeigen (was ich nicht glaube), kann man über kompliziertere
Methoden nachdenken.
Nimm einfach einen kurzzeitigen IIR Tiefpass (Butterworth), den Du immer
mit den aktuellen Werten neu fütterst. Dabei entsteht natürlich ein
Zeitversatz von einigen Samples in die Vergangenheit, aber bei
Wiedergabe ist das ja eh egal.
Possetitjel schrieb:> Jemin K. schrieb:>>> Nimm einfach einen kurzzeitigen IIR Tiefpass [...]>> Und das löst das Problem der unterschiedlichen Abtastraten> genau wie?
Indem es die hochfrequenten Anteile, die beim Wechsel von einem Sample
zum nächsten enstehen, wegfiltert
Wenn man schon dabei ist. Interpolieren bedeutet die Kurve geht durch
die Werte, waehrend Approximieren auch neben den Werten durchgehen kann.
Da man auf Messwerten Rauschen hat, wuerde man Approximieren. Ein
Tiefpdass interpoliert nicht, sondern approximiert auch.
Daher sind Interpolieren und tiefpassen ist nicht wirklich dasselbe.
Interpolieren, oder auch Approximieren kann auch bedeuten, dass man die
zweite, oder N-te Ableitung stetig haben will. So ein Vorgang kann dann
aber nicht mehr kausal sein, da man Werte aus der Zukunft benoetigt.
Also, mach dieses Fass nicht auf, lass es beim Tiefpass bewenden.
@ Gerhard (Gast)
>> Du lässt uns arg im Dunklen.> Sorry - manchmal ist es nicht leicht, sich in den Informationsbedarf> eines anderen hineinzuversetzen
Ist es so schlimm sich Gedanken darüber zu machen, was der Andere wissen
könnte, oder nicht, speziell wenn derjenige deine Arbeit machen soll?
Ich hoffe mal du bist noch Student oder Schüler.
Die oben von angedeutete einfache Lösung dürfte für den TO meines
Erachtens hinreichend sein. Die ganzen Filtergeschichten, Tiefpässe usw.
sind hier fehl am Platz.
Anscheinend wird hier nicht berücksichtigt/überlesen wohin die Messwerte
gehen, nämlich auf virtuelle Instrumente. Diese haben im allgemeinen die
Eigenschaft auf dem zuletzt übertragenem Wert stehen zu bleiben.
Gerhard schrieb:> Aber mir fehlt noch ein Ansatz zur Interpolation der> Messdaten, besonders bei den unterschiedlichen Abtastraten, mit denen> die einzelnen Parameter eingehen.
Wenn du interpolieren willst, brauchst du immer mindestens 2 aufeinander
folgende Messwerte für 1 Messgerät.
Daher die Frage: wie gross sind denn die Log-Files? Kannst du die Daten
komplett im Speicher des Rechners halten?
Wenn ja, dann ist es das einfachste, erst mal das Datenfile zu lesen
und die einzelnen Einträge in jeweilige Datenstrukturen für jedes Gerät
auseinanderklamüsern. Dann ist es leicht zu jedem Zeitpunkt
festzustellen, zwischen welchen beiden der jeweiligen Messreihen
interpoliert (linear?) werden muss.
Wenn nicht, dann muss man ein wenig mehr Aufwand mit einer oder mehreren
Queues treiben, in der momentan nicht gebrauchte Werte
zwischengespeichert werden können um im File auf den jeweils nächsten
zur Interpolation benötigten Messwert vorzulesen. Alternativ könnte man
noch mittels seek Orgien, Repositionierungen des Filepointers und
jeweils weiterlesen bis zum benötigten Datensatzes die Queues vermeiden.
Aber am einfachsten ist es, wenn du die Messreihen pro Messgerät einfach
komplett im Speicher halten kannst.
Karl H. schrieb:> Aber am einfachsten ist es, wenn du die Messreihen pro Messgerät einfach> komplett im Speicher halten kannst.
Ist doch nicht nötig, er möchte es doch nur abspielen. Was hindert
daran, im ersten Schritt zwei Dateien mit den interpolierten Messdaten
(mit 20 Hz) zu erstellen. Dann kann man sein Programm für die Anzeige
schreiben, dass nur noch mit den 2 Dateien gefüttert wird. Da kann man
immer etwas größere Blöcke einlesen und dann ausgeben.
Noch eleganter wäre es wahrscheinlich, wenn man die Messdaten z.B. mit
Splines approximieren würde, dann kann man sich den Datenmüll sparen.
Also nochmal:
Bastler schrieb:> Anscheinend wird hier nicht berücksichtigt/überlesen wohin die Messwerte> gehen, nämlich auf virtuelle Instrumente. Diese haben im allgemeinen die> Eigenschaft auf dem zuletzt übertragenem Wert stehen zu bleiben.
Was soll da die Interpoliererei bringen?
Gerhard schrieb:> Beispiel mit zwei Messgeräten mit 5 Hz und 2 Hz Abtastrate:> 001.002, messgerät1, 22.5, 22.7, 22.3, 22.0> 001.202, messgerät1, 22.5, 22.7, 22.4, 22.0> 001.369, messgerät2, 1020.0, 560.0, 552.7
Ich erklär es nochmal:
- Timmer auf 0.001 Interval, Timer starten
- Wenn Timer = Sample-Zeitpunkt dann Ausgabe auf Instrumente
So bleibt der Zeitbezug bei der Ausgabe gewahrt und durch die
ursprüngliche Abtastrate von 5Hz / 2 Hz ist eine zusätzliche
Interpolation Overkill, da die Virtuellen Instrumente eh immer auf dem
letzten Wert stehen bleiben. Oder will der TO eine super duper smooth
Anzeige? Da ist zum Abspielen und Ansehen nichts weiter notwendig.
Ganz einfache Lösung: Du updatest deine Werte einfach alle 50ms. Deine
interne Uhr nenne ich jetzt "t_disp".
Jedes Messgerät betrachtest du getrennt.
Dann suchst du dir den letzten Wert x1 raus, der bei t1 < t_disp
aufgenommen wurde und den ersten Wert x2, der bei t2 > t_disp
aufgenommen wurde.
Um jetzt den anzuzeigenden Wert zu bestimmen rechnest du
Es mag schönere Methoden geben, aber die hier ist wohl die einfachste
und für den Anwendungsfall vollkommen ausreichend. Da du eh jedes Gerät
getrennt betrachtest kann die die Samplerate und der Jitter auch
vollkommen egal sein.
Karl schrieb:> Karl H. schrieb:>> Aber am einfachsten ist es, wenn du die Messreihen pro Messgerät einfach>> komplett im Speicher halten kannst.>> Ist doch nicht nötig, er möchte es doch nur abspielen.
Er möchte interpolieren.
Des Menschen Wille ist sein Himmelreich.
Bastler schrieb:> Also nochmal:>> Bastler schrieb:>> Anscheinend wird hier nicht berücksichtigt/überlesen wohin die Messwerte>> gehen, nämlich auf virtuelle Instrumente. Diese haben im allgemeinen die>> Eigenschaft auf dem zuletzt übertragenem Wert stehen zu bleiben.>> Was soll da die Interpoliererei bringen?
Keine Ahnung. Vielleicht will er verhindern, dass die Zeiger durch die
Gegend springen. Sieht einfach netter aus, wenn ein Zeiger auf einer
Skala von 0 bis 100 nicht einfach von 20 auf 90 in einem Satz springt
sondern wenigstens ansatzweise so etwas wie Bewegung zeigt.
Karl H. schrieb:>> Was soll da die Interpoliererei bringen?>> Keine Ahnung. Vielleicht will er verhindern, dass die Zeiger durch die> Gegend springen. Sieht einfach netter aus, wenn ein Zeiger auf einer> Skala von 0 bis 100 nicht einfach von 20 auf 90 in einem Satz springt> sondern wenigstens ansatzweise so etwas wie Bewegung zeigt.Bastler schrieb:> Oder will der TO eine super duper smooth Anzeige?
Da sich der TO nicht mehr meldet kann man eh nur raten.
Karl H. schrieb:> Keine Ahnung. Vielleicht will er verhindern, dass die Zeiger durch die> Gegend springen. Sieht einfach netter aus, wenn ein Zeiger auf einer> Skala von 0 bis 100 nicht einfach von 20 auf 90 in einem Satz springt> sondern wenigstens ansatzweise so etwas wie Bewegung zeigt.
Wäre da nicht ein gleitender Mittelwert sinnvoller? Interpolation
erscheint mir eher dann sinnvoll, wenn man einen Graphen anzeigen will.
Hallo Gerhard,
Gerhard schrieb:> > Gibt es da schon Algorithmen für, die ich verwenden kann?
"Üblich" ist für so etwas z.B. eine spline Interpolation. Ich könnte mir
aber auch vorstellen, dass es ganz praktikabel ist, wenn Du z.B. ein
Polynom 3. Grades nimmst und damit die Werte zwischen zwei Messpunkten
zu interpolieren. Für das Polynom nimmst Du dann zwei Punkte vor dem
betrachten Zeitraum und zwei Punkte nach dem betrachteten Zeitraum (Du
kannst ja an der Stelle in die Zukunft gucken ;-)
mfg Torsten
Sheeva P. schrieb:> Wäre da nicht ein gleitender Mittelwert sinnvoller? Interpolation> erscheint mir eher dann sinnvoll, wenn man einen Graphen anzeigen will.
Er will ja nichts filtern. Ich würde auf jeden Fall ein Verfahren
wählen, dass zu den Zeitpunkten, zu denen auch Messwerte vorhanden sind,
diese Messwerte auch angezeigt werden.
Sheeva P. schrieb:> Karl H. schrieb:>> Keine Ahnung. Vielleicht will er verhindern, dass die Zeiger durch die>> Gegend springen. Sieht einfach netter aus, wenn ein Zeiger auf einer>> Skala von 0 bis 100 nicht einfach von 20 auf 90 in einem Satz springt>> sondern wenigstens ansatzweise so etwas wie Bewegung zeigt.>> Wäre da nicht ein gleitender Mittelwert sinnvoller?
Es geht doch darum, aufgezeichnete Messwerte möglichst genau so zu
reproduzieren wie sie derjenige gesehen hat, der vor den echten Anzeigen
gestanden hat.
Wenn um 17:35:02 der Messwert 90 war, dann muss der Replay das auch
genau so wiedergeben (wenn es genau zu diesem Zeitpunkt einen Eintrag im
Log gegeben hat). Eine Anzeige von 85 ist nicht akzeptabel, weil sich
der gleitende Mittelwert von 50 kommend, noch nicht auf die 90 zubewegt
hat. Und wenn die echten Anzeigen einen Messwert-'Schlenkerer' drinnen
hatten, bei dem die Nadel kurzzeitig von 50 auf 90 und 2s später wieder
zurück auf 50 gewackelt hat, dann muss das im Replay auch genau so
wiedergegeben werden und darf nicht ausgefiltert werden.
Karl H. schrieb:> Sheeva P. schrieb:>> Wäre da nicht ein gleitender Mittelwert sinnvoller?>> Es geht doch darum, aufgezeichnete Messwerte möglichst genau so zu> reproduzieren wie sie derjenige gesehen hat, der vor den echten Anzeigen> gestanden hat.>> Wenn um 17:35:02 der Messwert 90 war, dann muss der Replay das auch> genau so wiedergeben (wenn es genau zu diesem Zeitpunkt einen Eintrag im> Log gegeben hat). Eine Anzeige von 85 ist nicht akzeptabel, weil sich> der gleitende Mittelwert von 50 kommend, noch nicht auf die 90 zubewegt> hat. Und wenn die echten Anzeigen einen Messwert-'Schlenkerer' drinnen> hatten, bei dem die Nadel kurzzeitig von 50 auf 90 und 2s später wieder> zurück auf 50 gewackelt hat, dann muss das im Replay auch genau so> wiedergegeben werden und darf nicht ausgefiltert werden.
Da hast Du natürlich Recht. Aber dann ist die Sache doch noch einfacher:
ich habe einen Zeitpunkt A mit einem Meßpunkt m(A) und einen Zeitpunkt B
(A + Δt) mit einem Meßpunkt m(B). Außerdem habe ich zwischen den beiden
Zeitpunkten A und B verschiedene Zeitpunkte C1...Cn, bestimmt vom
Intervall der Anzeige -- erfreulicherweise sind die Abstände zwischen
den einzelnen Zeitpunkten konstant, nennen wir sie hier einfach mal ΔD
(delta Display).
Also berechne ich zunächst einmal die Differenz zwischen meinen beiden
Meßwerten (m(B) - m(A)) und teile diese durch mein Anzeigeintervall ΔD,
dann erhalte ich die Strecke, um die sich mein Meßwert während meines
Anzeigeintervalls verändert hat. Dies multipliziere ich mit der Anzahl
meiner seit dem letzten Meßpunkt abgelaufenen Anzeigeintervalle x(Cx),
zuletzt addiere ich das Ergebnis zu meinem Meßwert zu Beginn meines
Meßintervalls:
1
wert = m(A) + ( ( m(B) - m(A) ) / ΔD ) * x(Cx)
Das C++-chen im Anhang sollte das Gewünschte tun (ungetestet).
Sheeva P. schrieb:> Da hast Du natürlich Recht. Aber dann ist die Sache doch noch einfacher:
Sagen wir doch.
Die einzige 'Schwierigkeit' besteht darin, dass er für eine bestimmtes
Messgerät beim Lesen der nächsten Zeile aus der Datei nicht automatisch
den nächsten Wert kriegt, sondern dass sich da für ein anderes Messgerät
gleich ein paar Werte dazwischen gemogelt haben können, weil die
Abtastintervalle unterschiedlich sind. Das ist aber eine reine Frage der
Organisation, wie man das löst.
Er kriegt das schon hin.
Gerhard schrieb:> Gibt es da schon Algorithmen für, die ich verwenden kann?
Jede deiner Messreihen kannst du über ein Kalman-Filter laufen lassen
und damit auch noch Wissen über den Prozess und deine Messqualität in
die Interpolation der Anzeige einfließen lassen.