Hallo, brauche folgende Anwendung: eine .ild Datei in C# auslesen (für eine Lasershow). Brauche keine fertigen Code. Gibt es jedoch irgendwo ein gutes Tutorial oder eine Anleitung? Bitte um kurze Rückmeldung. MfG Tobias
Hallo Tobias, das kommt darauf an, ob das .ild ein Textfile oder ein binäres File ist. Für Text: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-read-from-a-text-file Für binär: https://docs.microsoft.com/en-us/dotnet/api/system.io.binaryreader --jmp
...und hier die "andere" seite: https://www.ilda.com/technical.htm Dort insb. "ILDA Image Data Transfer Format"
Hallo, keine Ahnung was .ild für ein Dateiformat ist. Im Anhang sieht man, dass der ausgegebene Code komisch ist. MfG Tobias
Tobias K. schrieb: > keine Ahnung was .ild für ein Dateiformat ist. Dann belasse es besser dabei. Es sind XY-RGB-Daten zu einzelnen Stützpunkten die per Laser abgefahren werden. Wenn Du der Meinung bist, dass der > Im Anhang sieht man, dass der ausgegebene Code komisch ist. dann wirst Du es auch nicht hin bekommen einen Parser dafür zu bauen. Btw. gibt es auch noch mehrere ILDA-Formate teilweise mit Farbpaletten usw.
Ich frage genau deswegen im Forum, weil ich es eben nicht hinbekomme einen geeigneten Parser zu bauen. ;) Gibt es irgendwelche Hilfestellungen im www, habe schon gesucht aber vergeblos
Ich würde vorschlagen die Spezifikation zu lesen und danach implementieren. Fertig. Lächerliche 22 Seiten, Überall im Internet zu finden.
Wo finde ich so wichtige Infos? Suchen wie ILDA Files auslesen, etc. waren nicht sehr hilfreich :(
Stephan schrieb: > z.B. in meinem Beitrag von 14:03 Und - wo ist der fertige Arduino-Code dazu? Mach mal hin ;-)
Hugo H. schrieb: > Stephan schrieb: >> z.B. in meinem Beitrag von 14:03 > Und - wo ist der fertige Arduino-Code dazu? Mach mal hin ;-) s.u.a: Tobias K. schrieb: > Brauche keine fertigen Code. ;) Lieber TO: (kannst/willst/magst keinen Parser schreiben) || (weisst Du nicht wie das ILDA File-Format ist) Für zweiteres: steht doch in der obigen Format-Beschreibung. ILDA.org war so freundlich, Dir das sogar alles aufzuschreiben. Für ersteres: wie immer: was hast Du denn schon in (C#) codiert? und wo klemmt's genau...?
Hallo, Hier mein bisheriger Code:
1 | using System; |
2 | using System.Collections.Generic; |
3 | using System.Linq; |
4 | using System.Text; |
5 | using System.Threading.Tasks; |
6 | using System.IO; |
7 | |
8 | namespace test_ilda |
9 | {
|
10 | class Program |
11 | {
|
12 | static void Main(string[] args) |
13 | {
|
14 | FileStream fs = new FileStream("bandsag.ild", FileMode.Open); |
15 | BinaryReader br = new BinaryReader(fs); |
16 | |
17 | int ausgabe; |
18 | |
19 | for(int i = 0; i<100;i++) //100 ist eine beliebige Zahl :) |
20 | {
|
21 | ausgabe = br.ReadInt32(); |
22 | Console.WriteLine(ausgabe); |
23 | }
|
24 | |
25 | |
26 | Console.ReadLine(); |
27 | }
|
28 | |
29 | }
|
30 | }
|
Problem: Was mache ich mit diesen Werten? Habe die .pdf schon 100x durchgelesen, kenne mich jedoch nicht aus.
:
Bearbeitet durch User
Tobias K. schrieb: > Problem: Was mache ich mit diesen Werten? Mal ganz blöd gefragt: wenn du nicht weißt, was das Datenformat überhaupt darstellt, und nicht weißt, was du mit dem Daten machen sollst, warum willst du da was parsen? Oliver
Warum werde ich wohl in einem Forum fragen? Genau, weil ich mich nicht auskenne. Deshalb gibt es ja ein FORUM um Hilfe von anderen zu bekommen, und keine abwägigen Kommentare zu erhalten. Anstatt mir unnützes Wissen reinzudrücken (ich möchte diejenigen jetzt nicht ansprechen, die mir schon besser geholfen haben mit Links zu hilfreichen Seiten, etc.) könntet ihr mir helfen oder es einfach lassen. Punkt aus!
Und? Hast du das Data-Dokument auch gelesen? Die Daten beginnen mit einem Header. Dazu steht in dem Dokument:
1 | 4.2. Field Description |
2 | 4.2.1. "ILDA" |
3 | Bytes 1 – 4. The ASCII letters ILDA, identifying an ILDA format header. |
4 | … |
Du kannst jetzt mal raten, was dir diese Worte sagen wollen. Wenn du drauf kommst, gehe weiter zu Byte 5 ff. Wenn nicht, such dir ein anderes Hobby. Oliver
Tobias K. schrieb: > ausgegebene Code komisch ist. 1.) Wenn Du diese Ausgabe mit dem von Dir dargestellten Progrämmchen erstellt hast, dann ist VOR den eigentlichen ILDA-Daten noch etwas anderes (gefühlt 2kByte) Die ILDA Daten fangen mit "ILDA" im Header an... Das ist bei anderen IDLA-Files (die ich im Netz gefunden habe) auch so. Auch die Datei "bandsag.ild" (die man ebenfalls im Netzfindet) fängt korrekterweise mit "ILDA" an... Irgedwas ist also schon mal an Deiner Datei "krumm"... 2.) Ansonsten: Byte(-gruppen)-weise nach einlesen und die eingelesenen Daten in Deine programminternen Strukturen/Klassen schreiben/mappen... Schematisches Beispiel: Byte(s) [1..4] nach HEADER.ILDA_ID[4] Byte(s) [5..7] nach HEADER.RSVD_1[3] Byte(s) [8] nach HEADER.FORMATCODE[1] ... Byte(s) [32] nach HEADER.RSVD_2[1] Durch die Daten dann blockweise UND FormatCode-längenabhängig durchiterieren. Endianess prüfen! 3.) Was auch immer Du dann mit den Daten machen möchtest... nur zu.
Das ILDA Format ist recht simpel aufgebaut, meisst aus gleich großen Einträgen, die jeweils über einen Header erkannt werden. Für einen Player (in C auf Cortex-M3) habe ich die komplette Spec in mehrere struct/union gegossen, so kann man da ganz einfach durchspazieren und spart sich buffer increments. Achtung: Alle 16Bit Daten sind BE! https://www.ilda.com/resources/StandardsDocs/ILDA_IDTF14_rev011.pdf Vom Prinzip her:
1 | typedef _PACKED struct { // 1..32 |
2 | _PACKED union { |
3 | unsigned char buf[32]; // 32 byte |
4 | |
5 | _PACKED struct { |
6 | _PACKED union { |
7 | char key[4]; // 1..4 "ILDA" |
8 | unsigned int keyNum; |
9 | |
10 | _PACKED struct { |
11 | char key1; |
12 | char key2; |
13 | char key3; |
14 | char key4; |
15 | };
|
16 | };
|
17 | |
18 | char ZERO0; // 5 |
19 | char ZERO1; // 6 |
20 | char ZERO2; // 7 |
21 | char formatCode; // 8 Format Code |
22 | |
23 | _PACKED union { |
24 | char frameName[8]; // 9..16 Frame Name |
25 | char paletteName[8]; // 9..16 Palette Name |
26 | };
|
27 | |
28 | char companyName[8]; // 9..16 Frame Name |
29 | |
30 | _PACKED union { |
31 | short totalPoints; // 25..26 Total points |
32 | short totalColors; // 25..26 Total colors |
33 | };
|
34 | |
35 | _PACKED union { |
36 | short frameNumber; // 27..28 Frame Number |
37 | short paletteNumber; // 27..28 Palette Number |
38 | };
|
39 | |
40 | short totalFrames; // 29..30 Total Frames |
41 | char scannerHead; // 31 Scanner Head |
42 | char future; // 32 Reserved for future use |
43 | };
|
44 | };
|
45 | } ILDA_Header_t; |
:
Bearbeitet durch User
Random .. schrieb: > Achtung: Alle 16Bit Daten sind BE! Dass diese Abkürzung mit Indianern zu tun hat ist nicht jedem Anfänger klar, daher dürftest du hier ruhig ohne Abkürzung schreiben.
weiter weg schrieb: > Random .. schrieb: >> Achtung: Alle 16Bit Daten sind BE! > > Dass diese Abkürzung mit Indianern zu tun hat ist nicht > jedem Anfänger klar, daher dürftest du hier ruhig ohne > Abkürzung schreiben. Werd ich dann beim nächsten Frühstücks-Ei machen 🙈 🤣🤣🤣 Für die nicht eingew(ei)hten: BE = Big Endian. Die Motorola-CPUs, welche für die ersten ILDA Anwendungen verwendet wurden, speichern und bearbeiten ihre Daten im Big Endian Format. Für gängige Mikrocontroller und den PCs muss man das nach LE = Little Endian konvertieren, was bei 16 Bit im Endeffekt eine Vertauschung der beiden Bytes bedeutet. Auf dem Cortex-M recht elegant per Intrinsic lösbar:
1 | uint16_t outVal = __REVSH(inVal); |
Achso, was hat das ganze mit dem Frühstücks-Ei zu tun? Die Frage nach BE/LE ist fast so alt wie die, auf welcher Seite man das Ei am besten aufschlägt 🤣 Beides hat Vor- und Nachteile, LE scheint sich mehr durchgesetzt zu haben.
:
Bearbeitet durch User
Beim nächsten Erscheinen von LE/BE ist es wieder scheisse weil Abkürzungen mit zwei Buchstaben einfach zu wenig Eindeutigkeit bzw. Aussagekraft haben.
weiter weg schrieb: > Beim nächsten Erscheinen von LE/BE ist es wieder scheisse > weil Abkürzungen mit zwei Buchstaben einfach zu wenig > Eindeutigkeit bzw. Aussagekraft haben. Der kontextbasierte Leser weiss mehr!
Random .. schrieb: > Der kontextbasierte Leser weiss mehr! ... erst ab dem Zeitpunkt ab dem er mit der unzulänglichen Abkürzung vertraut gemacht worden ist. weiter weg schrieb: > Beim nächsten Erscheinen von LE/BE ist es wieder scheisse meint dass ein neuer Thread mit dieser Abkürzung unter den selben Missverständnissen bzw. Uneindeutigkeiten zu leiden hat.
Oliver S. schrieb: > Und? Hast du das Data-Dokument auch gelesen? Möglicherweise kann er seine Schuhe selbst binden :-)
Tobias K. schrieb: > Hier mein bisheriger Code: Ohje, das ist ja nicht viel mehr als Öffnen und Dateinhalt ausgeben. Parsen von Binärdateien hast Du vermutlich noch nie gemacht? Ich habe mal kurz gesucht, aber ein wirkliches Beispiel in C# an dem Du dich langhangeln könntest habe ich dafür nicht gefunden. Vielleicht mal so als Startpunkt: Im Prinzip musst du die Datei Stück für Stück einlesen und die einzelnen Datenelemente enstprechende der Spezifikation interpretieren. Fangen wir mal mit dem Header an: ILDA_IDTF14_rev011.pdf, Figure 2: Achtung ich habe wenig ahnung von C#. Offsets in der Spec sind 1 referenziert ( normalerweise beginnt man bei 0)
1 | BinaryReader br = new BinaryReader(fs); |
2 | |
3 | byte[] header = new byte[32]; |
4 | |
5 | /* read header */ |
6 | br.Read(header, 0, 32); |
7 | |
8 | if(header[0:4] != "ILDA") |
9 | parse_error(); |
10 | |
11 | /* read format code offset 8 */ |
12 | byte format_code = BitConverter.ToUInt8(header, 8 - 1); |
13 | |
14 | byte[] palette_name = header[9-1:16-1]; |
15 | byte[] company_name = header[17-1:24-1]; |
16 | |
17 | /* ILDA data is big endian, need to swap bytes */ |
18 | if (BitConverter.IsLittleEndian) |
19 | { |
20 | Array.Reverse(header, 25-1,2); |
21 | Array.Reverse(header, 27-1,2); |
22 | ... |
23 | } |
24 | |
25 | uint number_of_records = BitConverter.ToUInt16(header, 25-1); |
26 | ... |
Und so weiter. [Edit:] Nachtrag der Code oben ist nur als Startpunkt zu sehen, da lässt sich noch einiges massiv optimieren oder besser kapseln. Paar Syntaxfehler korrigiert, lesen sollte man auch können :-). [Edit2]: Brauch mehr Kaffee ...
:
Bearbeitet durch User
Random .. schrieb: > Einträgen, die jeweils über einen Header erkannt werden. > Für einen Player (in C auf Cortex-M3) habe ich die komplette Spec in Ich weis nicht wie Deine Compiler/MPU settings sind, aber Packing alleine kann bewirken, dass der Compiler beim Zugriff jedes Byte einzeln einliest und dann zusammensetzt. Das ergibt dann sehr viele Instruktionen. Wenn man weis, das die Datenstruktur immer auf anständig alignten Adresse liegt, dann kann man beim gcc zusätzlich zum packing das alignment Attribut nutzen um dem compiler zu hefen. Bei parse-lastigen Funktionen kann das zu einer drastischen Code Reduktion und Performanceverbesserung führen. (Das Byte-weise Einlesen eines uint32_t benötigt 7 einzelne Instruktionen) Ich habe bei dem folgenden Beispiel absichtlich mal das compiler flag angeschaltet, so das der gcc sich nicht auf die MPU verlässt. Es kommt auch ein bisl auf die Hardware/Speicherbereich an, wo man sich bewegt ob ein unalignter Zugriff ne Excpetion auslöst oder von der MPU/MMU korrekt behandelt wird) https://godbolt.org/z/E7eejPGrG
Andreas M. schrieb: > aber Packing > alleine kann bewirken, dass der Compiler beim Zugriff jedes Byte einzeln > einliest und dann zusammensetzt. Die Daten werden in einen globalen Byte-Buffer per fread() eingelesen, und dann über Pointer auf die structs und deren Member verarbeitet. Da sollte nichts schiefgehen, und mir ist im Assembly auch nichts aufgefallen. Die structs sind dicht, __packed dient nur dazu, dass der Compiler nicht auf dumme Gedanken kommt, wie z.B. das Umsortieren oder komplette Zerreissen eines structs im Speicher. Die structs dienen letzlich nur als Schablone zum Ablesen der Daten.
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.