For-Schleife läuft ohne printf nicht durch...
-
Dann würde der Kompiler meckern.
Aber kompilieren kann ich ja problemlos.
Die Identifikation des Sensors funktioniert problemlos. Nur an dem Punkt, wo ich das "check" bekommen sollte, passiert nichts mehr.
-
Woah! entscheide dich mal, ob du C oder C++ machst. Kein Wunder, dass du da irgendwo undefiniertes Verhalten bekommst, denn Mischung von C und C++ geht praktisch immer schief.
Das ist immer noch kein vollständiges Programm. Lies dir mal den dritten Link in meiner Signatur durch und halte dich da dran.
Verdächtig sind hier die Zeilen -50 bis 80, ganz besonders stechen folgende heraus:
80: Irgendwo fehlt eine Klammer
6: Höchst ungewöhnlicher Umgang mit einem vector
9: Häh?
15: Merkwürdiger Kommentar
17: Sinn?
21-28: sinnlos?
29: Sinn?
31: Mathematisch korrekt?
36-60: Oh, ein for-switch Idiom als if getarnt!
64-69: Richtig geklammert?
69-75: sinnlos?
-
pet wird am anfang inkrementiert.
Rhetorische Frage:
messwerte ist also eindouble messwerte[devInfo.numberOfChannels][ARRAYSIZE+1]
?Und ich hatte recht: der Code wurde superverkompliziert. Versuch da nochmal ein paar logische Umformungen zur Vereinfachung durchzuführen.
-
SeppJ schrieb:
Woah! entscheide dich mal, ob du C oder C++ machst. Kein Wunder, dass du da irgendwo undefiniertes Verhalten bekommst, denn Mischung von C und C++ geht praktisch immer schief.
Das ist immer noch kein vollständiges Programm. Lies dir mal den dritten Link in meiner Signatur durch und halte dich da dran.
Verdächtig sind hier die Zeilen -50 bis 80, ganz besonders stechen folgende heraus:
80: Irgendwo fehlt eine Klammer
6: Höchst ungewöhnlicher Umgang mit einem vector
9: Häh?
15: Merkwürdiger Kommentar
17: Sinn?
21-28: sinnlos?
29: Sinn?
31: Mathematisch korrekt?
36-60: Oh, ein for-switch Idiom als if getarnt!
64-69: Richtig geklammert?
69-75: sinnlos?Okay, legen wir mal los:
80 - Nein, es wirkt vielleicht so, weil es unkonsistent eingerückt war. Ich hab das mal in meinem Code verbessert. Mit kdevelop sehe ich beim anklicken eienr Klammer immer farblich zwischen den Bereich zwischen den Klammern hervorgehoben. Von daher kann ich sehr schnell und genau sehn, wozu jede Klammer gehört.
6 - Das entspringt dem Beispielcode des Sensorherstellers aus der OakLib.
9 - net = Anzahl der Gesamtmesswerte, damit ich prüfen kann, ob nach evtl. 30000 Messungen der Code abricht. Ist mehr ne Hilfestellung. pet = heir triffts die Bezeichnung Arrayposition eher. Die Größe ist als Preprozessor-Definition festgelegt. pet durchwandert das Array zur Auffüllung des Arrays.
15 - naja, hier gehts um die Channels des Sensors. Channel 0 = frame in Sekunden. sollte hier i=1 sein, wird die erste Spalte des Arrays nicht gefüllt. Ich habe mich inzwischen entschieden, alle Spalten zu füllen und lediglich die Sekunden nicht auszuwerten.
17 - Ich habs nicht geschafft, das i der For-Schleife, in der wir uns befinden, auszulesen. Statt dessen bekomme ich als i immer den chanInfo.channelName.c_str() ausgegeben. Den Grund konnte ich nicht finden.
21-28 - stimmt, hab ich gelöscht. Stammte noch aus dem Beispielcode, sonstige Codefragmente darin hatte ich wegrationalisiert, daher nun kein Sinn mehr.
29 - auch hier muss ich dir Recht geben. Hab die Abfrage gelöscht.
31 - japp, hab ich extra getestet, da ich hiermit unlesbare Sensorwerte in verständliche Werte konvertiere.
36-60 - hast ja wieder mal recht. Das war mir zwischendrin auch aufgefallen, aber ich hielt es vorläufig nicht relevant genug, es zu ändern, da ich noch nicht sicher war, ob der Code bestehen bleibt.
69-75 - Warum sinnlos? Ich möchte ja wissen, ob der Code hier ankommt. Das diente der Fehlersuche. die Auswertungs des Arrays habe ich wieder gelöscht, weil sie nicht funktioneirte - wie ich hiermit rausgefunden habe, liegt das daran, dass ich hier gar nicht erst ankomme, wenn ich den Zeilenumbruch in der printf-Anweisung lösche.So viel Mühe du dir bei der Suche nach potentiellen Fehlern gemacht hast...besteht das Problem leider immer noch. Ich schreib mal grade die If-Abfragen zum Switch um und dann poste ich den bereinigten Code.
Die Entscheidung, ob ich C oder C++ schreibe, liegt nicht bei mir. Ich kann kein C++...und kenne nur Basics in C. Aber die OakLib mit dem Beispielcode basiert auf C++. Da C wohl vollständig kompatibel zu C++ sein soll, müsste es also eigentlich keine Probleme geben - zumindest nich bei so 'einfachen' Anwendungsfällen.
-
So, hier der etwas sauberere Code, der jedoch noch immer noch den selben Fehler enthält:
for (;;) // Starten des Auslesens { usleep(SLEEPVALUE); std::vector<int> values; CHECK_OAK_CALL(readInterruptReport(deviceHandle, values)); net++; // Gesamtdurchläufe pet++; // Arrayposition // printf ("\nn: %d\t", net); // Auslesen aller Kanäle for (int i = 0; i < devInfo.numberOfChannels; i++) // i=0 wenn man den Sekundenwert anzeigen möchte... { j++; double neuwert; double multiplikator; ChannelInfo& chanInfo = channelInfos[i]; neuwert = values[i]; multiplikator = pow(10.00, chanInfo.unitExponent); // Umrechnung der Werte und Abspeichern im Array switch (i) { case 0: messwerte[i][pet] = neuwert; break; case 1: messwerte[i][pet] = neuwert; break; case 2: messwerte[i][pet] = neuwert/M_PI * 180 * multiplikator; // printf(" \n", messwerte[i][pet]); break; case 3: messwerte[i][pet] = neuwert/M_PI * 180 * multiplikator; break; default: printf("Fehler beim Switch"); break; } // Zählvariable zurücksetzen und Array auswerten if (pet == ARRAYSIZE) { pet = 0; for (int i=0; i<devInfo.numberOfChannels-3; i++) { printf("check!"); } } } }
Wenn ich die Werte im Switch direkt ausgebe, funktionierts:
switch (i) { case 0: messwerte[i][pet] = neuwert; printf("0: %lf\t", messwerte[i][pet]); break; case 1: messwerte[i][pet] = neuwert; printf("1: %lf\t", messwerte[i][pet]); break; case 2: messwerte[i][pet] = neuwert/M_PI * 180 * multiplikator; printf("2: %lf\t", messwerte[i][pet]); // printf(" \n", messwerte[i][pet]); break; case 3: messwerte[i][pet] = neuwert/M_PI * 180 * multiplikator; printf("3: %lf\n", messwerte[i][pet]); break; default: printf("Fehler beim Switch"); break; }
0: 133.000000 1: 9856.000000 2: 89.570492 3: 179.834263 0: 470.000000 1: 9746.000000 2: 89.610599 3: 179.679565 0: 490.000000 1: 9790.000000 2: 89.513196 3: 180.097824 0: 510.000000 1: 9746.000000 2: 89.513196 3: 179.943125 0: 530.000000 1: 9842.000000 2: 89.570492 3: 180.097824 0: 550.000000 1: 9746.000000 2: 89.438712 3: 179.903018 0: 570.000000 1: 9834.000000 2: 89.347039 3: 180.000421
usw.
In diesem Fall kann ich den Zeilenumbruch auch weglassen und ich bekomme problemlos eine Ausgabe.
Was mich jedoch verwirrt ist die Tatsache, dass in den ersten beiden Spalten des Arrays Werte gespeichert sind, die länger als 8 Zeichen sind. Der Dateityp double sollte doch 8 Stellen lang wein, oder?!
double messwerte[4][ARRAYSIZE];
-
Cysign schrieb:
80 - Nein, es wirkt vielleicht so, weil es unkonsistent eingerückt war. Ich hab das mal in meinem Code verbessert. Mit kdevelop sehe ich beim anklicken eienr Klammer immer farblich zwischen den Bereich zwischen den Klammern hervorgehoben. Von daher kann ich sehr schnell und genau sehn, wozu jede Klammer gehört.
Das habe ich doch nicht von Hand gezählt, sondern ebenfalls von meiner IDE machen lassen. Folglich hast du einen anderen Code vorliegen als du uns gezeigt hast. Ich wiederhole noch einmal meinen dringenden Verweis auf den dritten Link in meiner Signatur. Ohne ausführbaren Code können wir dir nicht helfen, Fehler zu finden, die erst bei der Ausführung auftreten.
Noch drei Bemerkungen:
1. Da du eine exotische Bibliothek benutzt, wäre es gut, wenn du für uns die Aufrufe an diese Bibliothek ersetzt, z.B. den vector mit irgendwelchen Dummywerten füllst.
2. Höchstwahrscheinlich liegt der Fehler sowieso ganz woanders. Was du beschreibst ist ein lupenreiner Fall von undefiniertem Programmverhalten. Es kann gut sein, dass die eigentliche Ursache lange vor dem gezeigten Codeabschnitt liegt. Daher ist es hochgradig wichtig, dass du bei der Erstellung eines ausführbaren Beispiels darauf achtest, dass der Fehler nach jeder Kürzung des Codes tatsächlich noch auftritt.
3. Mit dem Code den du gezeigt hast, kann ich auch nicht mehr machen, als die verdächtigen Stellen zu markieren. Insgesamt habe ich mir schon Mühe dabei gegeben, kann aber aufgrund des fehlenden Kontextes nicht absolut sicher sein, ob es wirklich echte Fehler sind. Du solltest dir jedoch wirklich absolut sicher sein, dass es wirklich richtig ist, wenn du eine der von mir genannten Stellen für richtig erklärst. Deine Antwort kam dann doch ein bisschen schnell, ich denke, bei einigen Stellen hast du nicht ganz verstanden, was mich störte:80: Siehe oben
6: Sicher? Ganz sicher? Es ist höchst ungewöhnlich und wäre kein gutes Zeichen für die Bibliothek. Wobei es durchaus viele schlechte Bibliotheken gibt, daher nicht ausgeschlossen, dass es so sein soll.
9: Eine sich verändernde Arraygröße macht keinen Sinn. Die Beschreibung ist mindestens schlecht. Oder du hast etwas an deinem eigenen Code nicht verstanden. Außerdem: Ist net nicht gleich pet?
15: Was ist denn die semantische Bedeutung von dem i? Diese scheint wild zu wechseln. Nenn die Variable mal nicht i, sondern gib ihr einen beschreibenden Namen. Dann wird entweder dem Leser klar, was du meinst, oder du merkst, dass da selber etwas nicht stimmt. Je nachdem, was richtig ist.
17: Noch ein weitere Hinweis für undefiniertes Verhalten, wenn du dieses sinnlose j als Ersatz für i brauchst.
31: Ok, glaube ich dir mal. Ich hoffe, du bist wirklich sicher, dass es richtig ist.
64-69: Also soll die check-Schleife wirklich in dem Block zumif (pet == ARRAYSIZE)
stehen?
69: Wozu überhaupt die Schleife?P.S.: Bezüglich deines neuen Codes, habe ich nur kurz überflogen: Ich glaube du hast das mit dem for-switch nicht verstanden. Das war Sarkasmus. Ohne Sarkasmus gesagt: Das ist kompletter Unsinn, egal ob mit switch oder if.
-
Hmm...okay, vielleicht ist der komplette Code aussagekräftiger:
/// \file /// \date 2008-10-10 /// \author Xavier Michelon, Toradex SA /// /// \brief Sample program for using Oak device in Linux #include "OakHidBase.h" #include "OakFeatureReports.h" #include <stdio.h> #include <stdlib.h> #include <string> #include <math.h> #include <unistd.h> #define SAMPLEDELAY 20 // Set Report- und Sample-Rate - 20 #define ARRAYSIZE 50 // Anzahl der Werte #define SLEEPVALUE 23000 // Sleeptime zwischen Messwerten - 25000 evtl. 2300 using namespace std; using namespace Toradex::Oak; int net = 0; // Anzahl der Gesamtmessungen im kompletten Programmverlauf int pet = 0; // Array-Position int arraysize = 0; // Number of Samples double messwerte[4][ARRAYSIZE]; // 0: Framenumber [s] 1: Acceleration [m/m²] 2: Zenith [grad] 3: Azimuth [grad] // define some local constants namespace { string const& kDefaultDevice("/dev/usb/hiddev0"); ///< Default device, if not specified as an argument } /// \brief wrapper function for error report that add file, line and function in which an error occured #define CHECK_OAK_CALL(status) checkOakCall(status, __FILE__, __LINE__, __FUNCTION__) //************************************************************************************************* /// \brief Check the status code of a Oak library call. /// /// If the status is not OK, this function display an error message to the standard error output /// then quit the application /// /// Note This function is not to be called directly, but via the CHECK_OAK_CALL macro that /// insert the line, file and function where the error occured /// /// \param[in] status the status code to check /// \param[in] file The file where the error occured /// \param[in] line The line number where the error occured /// \param[in] function The name of the function where the error occured //************************************************************************************************* void checkOakCall(EOakStatus status, const char *file, int line, const char* function) { if (eOakStatusOK != status) { fprintf(stderr, "Error: %s in function %s (file %s, line %d)\n", getStatusString(status).c_str(), function, file, line); exit(1); } } //************************************************************************************************* /// \brief The program entry point /// /// \param[in] argc The number of arguments of the program /// \param[in] argv The argument list of the program //************************************************************************************************* int main(int argc, char **argv) { printf("\n \n \n"); // if the device file is not provided as an argument, we use a default value std::string device(argc >= 2 ? argv[1] : kDefaultDevice); int deviceHandle; CHECK_OAK_CALL(openDevice(device, deviceHandle)); // get the device informations DeviceInfo devInfo; CHECK_OAK_CALL(getDeviceInfo(deviceHandle, devInfo)); // Set the report Mode CHECK_OAK_CALL(setReportMode(deviceHandle, eReportModeAfterSampling, true)); EOakReportMode reportMode; CHECK_OAK_CALL(getReportMode(deviceHandle, reportMode, true)); // Set the LED Mode CHECK_OAK_CALL(setLedMode(deviceHandle, eLedModeOff, true)); EOakLedMode ledMode; CHECK_OAK_CALL(getLedMode(deviceHandle, ledMode, true)); // Set the report rate CHECK_OAK_CALL(setReportRate(deviceHandle, SAMPLEDELAY, true)); unsigned int reportRate; CHECK_OAK_CALL(getReportRate(deviceHandle, reportRate, true)); printf("Report rate: %u\n", reportRate); // Set the sample rate CHECK_OAK_CALL(setSampleRate(deviceHandle, SAMPLEDELAY, true)); unsigned int sampleRate; CHECK_OAK_CALL(getSampleRate(deviceHandle, sampleRate, true)); printf("Sample rate: %u\n", sampleRate); // Retrieve Channel infos std::vector<ChannelInfo> channelInfos(devInfo.numberOfChannels); for (int i = 0; i < devInfo.numberOfChannels; i++) { ChannelInfo& chanInfo = channelInfos[i]; CHECK_OAK_CALL(getChannelInfo(deviceHandle, i, chanInfo)); printf(" Name: %s\n", chanInfo.channelName.c_str()); } for (;;) // Starten des Auslesens { usleep(SLEEPVALUE); std::vector<int> values; CHECK_OAK_CALL(readInterruptReport(deviceHandle, values)); net++; // Gesamtdurchläufe pet++; // Arrayposition // printf("Anzahl der Messungen: %d\t", net); // Auslesen aller Kanäle for (int i = 0; i < devInfo.numberOfChannels; i++) { double neuwert; double multiplikator; ChannelInfo& chanInfo = channelInfos[i]; neuwert = values[i]; multiplikator = pow(10.00, chanInfo.unitExponent); // Umrechnung der Werte und Abspeichern im Array switch (i) { case 0: messwerte[i][pet] = neuwert; // printf("Ch0: %.0lf\t", messwerte[i][pet]); printf("%lf\t", neuwert); break; case 1: messwerte[i][pet] = neuwert; // printf("Ch1: %.0lf\t", messwerte[i][pet]); printf("%lf\t", neuwert); break; case 2: printf("%lf\t", neuwert); messwerte[i][pet] = neuwert/M_PI * 180 * multiplikator; // printf("Ch2: %.2lf\t", messwerte[i][pet]); // printf(" \n", messwerte[i][pet]); break; case 3: printf("%lf \n", neuwert); messwerte[i][pet] = neuwert/M_PI * 180 * multiplikator; // printf("Ch3: %.2lf\n", messwerte[i][pet]); break; default: printf("Fehler beim Switch"); break; } // Zählvariable zurücksetzen und Array auswerten if (pet == ARRAYSIZE) { pet = 0; for (int kanal=0; kanal<devInfo.numberOfChannels-3; kanal++) { printf("\n check! \n\n"); } } } } // Cleanup CHECK_OAK_CALL(closeDevice(deviceHandle)); return 0; }
Hierzu mal die Ausgabe beim Aufruf der makefile:
cysign@hp-lubuntu:~/Dropbox/aeros/oak/kdevelop/src$ make g++ -DHAVE_CONFIG_H -I. -I.. -g -O2 -MT oaklinux.o -MD -MP -MF .deps/oaklinux.Tpo -c -o oaklinux.o oaklinux.cpp mv -f .deps/oaklinux.Tpo .deps/oaklinux.Po /bin/bash ../libtool --tag=CXX --mode=link g++ -g -O2 -o oaklinux OakFeatureReports.o OakHidBase.o oaklinux.o g++ -g -O2 -o oaklinux OakFeatureReports.o OakHidBase.o oaklinux.o
Die Ausgabe lautet nun (Unveränderte Wiedergabewerte des Lib) :
cysign@hp-lubuntu:~/Dropbox/aeros/oak/kdevelop/src$ ./oaklinux Report rate: 20 Sample rate: 20 Name: Frame Number [s] Name: Acceleration [m/s2] Name: Zenith [rad] Name: Azimuth [rad] 664.000000 9768.000000 12559.000000 31399.000000 983.000000 9717.000000 12549.000000 31389.000000 1023.000000 9797.000000 12556.000000 31416.000000 1043.000000 9709.000000 12575.000000 31423.000000 1063.000000 9753.000000 12556.000000 31433.000000 1083.000000 9746.000000 12546.000000 31377.000000 1103.000000 9731.000000 12578.000000 31406.000000 1123.000000 9761.000000 12566.000000 31389.000000 1163.000000 9775.000000 12598.000000 31380.000000 1183.000000 9753.000000 12595.000000 31380.000000 1203.000000 9761.000000 12536.000000 31389.000000 1223.000000 9731.000000 12549.000000 31367.000000 1243.000000 9731.000000 12578.000000 31377.000000 1263.000000 9717.000000 12588.000000 31399.000000 1283.000000 9724.000000 12585.000000 31341.000000 1323.000000 9783.000000 12549.000000 31433.000000 1343.000000 9753.000000 12566.000000 31341.000000 1363.000000 9753.000000 12546.000000 31416.000000 1383.000000 9775.000000 12529.000000 31389.000000 1403.000000 9753.000000 12546.000000 31380.000000 1423.000000 9797.000000 12520.000000 31416.000000 1463.000000 9753.000000 12556.000000 31380.000000 1483.000000 9761.000000 12578.000000 31389.000000 1503.000000 9724.000000 12598.000000 31399.000000 1523.000000 9753.000000 12546.000000 31416.000000 1543.000000 9775.000000 12578.000000 31380.000000 1563.000000 9797.000000 12556.000000 31399.000000 1603.000000 9746.000000 12578.000000 31399.000000 1623.000000 9753.000000 12566.000000 31399.000000 1643.000000 9717.000000 12549.000000 31389.000000 1663.000000 9717.000000 12539.000000 31399.000000 1683.000000 9753.000000 12529.000000 31389.000000 1703.000000 9724.000000 12546.000000 31380.000000 1723.000000 9746.000000 12559.000000 31389.000000 1763.000000 9797.000000 12556.000000 31416.000000 1783.000000 9709.000000 12529.000000 31399.000000 1803.000000 9753.000000 12556.000000 31389.000000 1823.000000 9739.000000 12559.000000 31389.000000 1843.000000 9775.000000 12556.000000 31389.000000 1863.000000 9731.000000 12566.000000 31377.000000 1903.000000 9746.000000 12568.000000 31399.000000 1923.000000 9775.000000 12595.000000 31406.000000 1943.000000 9717.000000 12559.000000 31389.000000 1963.000000 9731.000000 12556.000000 31377.000000 1983.000000 9739.000000 12588.000000 31406.000000 2003.000000 9761.000000 12588.000000 31416.000000 2023.000000 9694.000000 12614.000000 31399.000000 15.000000 9797.000000 12568.000000 31446.000000 35.000000 9768.000000 12510.000000 31406.000000 55.000000 check! 9746.000000 12585.000000 31377.000000 75.000000 9775.000000 12566.000000 31377.000000 95.000000 9775.000000 12566.000000 31380.000000 115.000000 9724.000000 12546.000000 31423.000000 155.000000 9761.000000 12566.000000 31380.000000 175.000000 9783.000000 12559.000000 31399.000000 195.000000 9761.000000 12559.000000 31406.000000 215.000000 9724.000000 12585.000000 31367.000000 235.000000 9761.000000 12536.000000 31367.000000 255.000000 9717.000000 12588.000000 31406.000000 295.000000 9739.000000 12566.000000 31399.000000 315.000000 9797.000000 12529.000000 31446.000000 335.000000 9739.000000 12595.000000 31341.000000 355.000000 9702.000000 12568.000000 31380.000000 375.000000 9768.000000 12536.000000 31377.000000 395.000000 9694.000000 12549.000000 31399.000000 415.000000 9761.000000 12539.000000 31389.000000 455.000000 9709.000000 12595.000000 31399.000000 475.000000 9709.000000 12539.000000 31389.000000 495.000000 9731.000000 12595.000000 31360.000000 515.000000 9775.000000 12539.000000 31433.000000 535.000000 9694.000000 12588.000000 31380.000000 555.000000 9739.000000 12575.000000 31416.000000 594.000000 9775.000000 12529.000000 31423.000000 615.000000 9709.000000 12549.000000 31399.000000 635.000000 9709.000000 12595.000000 31406.000000 655.000000 9775.000000 12546.000000 31389.000000 675.000000 9731.000000 12566.000000 31399.000000 695.000000 9702.000000 12595.000000 31367.000000 715.000000 9731.000000 12588.000000 31406.000000 755.000000 9790.000000 12527.000000 31433.000000 775.000000 9746.000000 12529.000000 31389.000000 795.000000 9753.000000 12529.000000 31399.000000 815.000000 9775.000000 12520.000000 31389.000000 835.000000 9768.000000 12536.000000 31399.000000 855.000000 9753.000000 12578.000000 31389.000000 895.000000 9739.000000 12566.000000 31380.000000 915.000000 9820.000000 12556.000000 31399.000000 935.000000 9731.000000 12529.000000 31350.000000 955.000000 9775.000000 12546.000000 31380.000000 975.000000 9753.000000 12595.000000 31416.000000 995.000000 9761.000000 12549.000000 31446.000000 1035.000000 9724.000000 12578.000000 31357.000000 1055.000000 9731.000000 12556.000000 31423.000000 1075.000000 9805.000000 12539.000000 31389.000000 1095.000000 9724.000000 12529.000000 31377.000000 1115.000000 9709.000000 12500.000000 31380.000000 1135.000000 9746.000000 12585.000000 31399.000000 1155.000000 9672.000000 12627.000000 31399.000000 1195.000000 9753.000000 12578.000000 31406.000000 1215.000000 check!
Welche IDE nutzt du denn, die dir die Klammerfehler anzeigt?
Ich vermute, dass der Wurm im Datentyp steckt.
Sollte ich das Array vielleicht mit "long double" erstellen?Die Arraygröße verändert sich nicht. Sie wird vom Preprozessor mit dem Wert von
#devine ARRAYSIZE
festgelegt. Sollte ich später feststellen, dass diese Anzahl an Messwerten nicht ausreicht, brauche ich so nur diesen Definewert zu verändern.
Ich hab j mal rausgeschmissen (wieder auch ein altes Codefragment...).
Bzgl. 31: Ja, da bin ich mir sicher. Wie du an diesen Rohwerten sehen kannst, wird da kein Mensch schlau. Wenn ich durch Pi teile und mit 180° Multipliziere, erhalte ich Kugelkoordinaten von 0-360° bzw. von 0-180° als Rückgabewert. Beim Drehen des Sensors sehe ich, dass das mit wen Werten passt.
Die Schleife im Block, in dem bisher "check" steht, dient der Auswertung des Arrays.
Warum soll Switch oder die If-Abfrage hier Schwachsinn sein? Ich muss doch die jeweiligen Daten dem Array richtig zuordnen und umrechnen.
Dies würde ich gerbe beim Eintragen ins Array machen.Da die Werte, die ich ins Array schreibe scheinbar länger sind als double, könnte dies den Fehler verursachen. Ich versuche es mal durch ein long double zu ersetzen.
Oder gibt es eine Möglichkeit, den genauen Datentyp herauszufinden?
Um ehrlich zu sein blicke ich bei der Lib selbst nicht durch...ich steh halt noch am Anfang meiner...langen Lernkurve
-
Ah, es lag tatsächlich am long double.
Jetzt funktionierts.
Danke, dass ihr euch die Mühe gemacht habt um mir auf die Sprünge zu helfen
Ich verzweifelte hier schon seit Stunden
-
Schau dir dein switch nochmal an stichwort dry (don't repeat yourself)
-
Vereinfache mal folgenden Code:
for (int i = 0; i < 2; ++i) { switch (i) { case 0: puts("Hello"); break; case 1: puts("World"); break; } }
P.S.: Dein Problem liegt übrigens so gut wie sicher nicht an dem Datentyp. Du schreibst irgendwo über Arraygrenzen oder ähnliches. Ohne ausführbaren Code ist das Programm jedoch zu lang, um das nachzuvollziehen. Da du geschrieben hast, dass du kdevelop benutzt, nehme ich mal an, dass du unter einem Linux mit GCC als Compiler entwickelst.
- Compiliere dein Programm mit den Compilerschaltern:
-O0 -g -D_GLIBCXX_DEBUG -Wall -Wextra
Jede Warnung des Compilers ist als Fehler anzusehen und zu beheben.
- Wenn dies geschehen ist: Lasse das Programm laufen. Wahrscheinlich bekommst du Fehlermeldungen. Vielleicht reichen diese schon zur Behebung des Problems.
- Falls keine Fehler auftraten oder du die Ursache nicht finden konntest, dann installiere das Programm valgrind (ist möglciherweise schon installiert). Starte dein Programm mit:valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes dein_programm
Behebe alle gemeldeten Fehler (nicht die unterdrückten). Falls Fehler bezüglich uninitialisierter Werte auftreten, deren Ursache du nicht finden kannst, dann starte das Programm mit
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes --track-origins=yes dein_programm
(ist sehr langsam, daher nur bei Bedarf. Verringere eventuell die Anzahl der Berechnungen, falls es zu langsam ist.)
Behebe alle gemeldeten Fehler.
- Falls keine Fehler mehr gefunden werden, aber das Programm immer noch falsch läuft, kannst du noch die valgrind-Option--tool=exp-sgcheck
ausprobieren.
-
puts("Hello World");
Ich weiß ehrlich nicht, wie ihr das meint.
Es gibt da bestimmt ne Möglichkeit, das kompakter darzustellen.
Aber ich wüsste nicht, wie das diesen Switch vereinahen soll.
-
Cysign schrieb:
Ich weiß ehrlich nicht, wie ihr das meint.
Ich wage mal zu behaupten, dass folgendes reicht:
for (;;) { usleep(SLEEPVALUE); std::vector<int> values; CHECK_OAK_CALL(readInterruptReport(deviceHandle, values)); const double mult2 = 180 / M_PI * pow(10.00, channelInfos[2].unitExponent); const double mult3 = 180 / M_PI * pow(10.00, channelInfos[3].unitExponent); messwerte[0][pet] = values[0]; messwerte[1][pet] = values[1]; messwerte[2][pet] = values[2] * mult2; messwerte[3][pet] = values[3] * mult3; ++net; pet=(pet+1) % ARRAYSIZE) }
Was auch immer das ursprüngliche Problem mit long double zu tun hatte...
Mein Einwand, dass Du am letzten Arrayelement vorbeigreifst gilt übrigens immer noch - ist aber untergegangen. Alldieweil ist pet im Code oben im Intervall [0, ARRAYSIZE).
-
Cysign schrieb:
puts("Hello World");
Ich weiß ehrlich nicht, wie ihr das meint.
Es gibt da bestimmt ne Möglichkeit, das kompakter darzustellen.
Aber ich wüsste nicht, wie das diesen Switch vereinahen soll.Wie hast du es denn beim Hello World geschafft? Hast du mal den Link gelesen, den ich dir am Anfang von Seite 2 gegeben habe?
Ich habe dir in meinem letzten Beitrag übrigens noch wichtige Hinweise reineditiert, während du schon geantwortet hast. Solltest du mal lesen.
-
Puh, gar nicht so einfach, das alles aufzunehmen.
Aber der Codeblock von Furble Wurble sieht interessant aus. Probier ich mal aus^^Linker für -Wall z.B. ist mir bekannt. Aber ich werd aus der Makefile nicht ganz schlau.
Bisher kenn ich nur makefiles mit <10 Zeilen. Hier jedoch wurde die Makefile über automake generiert. Ich weiß nicht, wie ich die Linker richtig hinzufügen kann. Und mir 637 Zeilen ist diese nicht grade kompakt und leicht zu verstehen für mich.Programmieren müsste man können
-
Da ist bestimmt ein configure-Programm dabei.
Außerdem:
Hast du das Programm denn nicht selber geschrieben? Dann musst du doch auch wissen, wie man es übersetzt. Du sollst nicht nach Fehlern in der Bibliothek suchen, sondern du sollst dein Programm mit diesen Optionen übersetzen und starten.
Mit Linkern hat dies auch überhaupt nichts zu tun. Alles sehr wirr. Vielleicht führst du dir noch ein bisschen mehr Anfängerliteratur zu Gemüte (zweiter Link in meiner Signatur). Ich habe den Eindruck, viel Verwirrung in diesem Thread entsteht, weil du dich nicht richtig ausdrücken kannst und Wörter benutzt, deren Bedeutung du nicht richtig verstehst.
-
Genau, die Make-Datei wird erst mit dem configure-Programm erstellt.
Wie ich bereits erwähnte, kenne ich nur ein paar C-Basics. Ich nage mich da quasi irgendwie durch und hoffe, dass ich das Ergebnis bekomme, das ich wünsche
Ich hab mir gestern ein O'Reilly C++-Buch gekauft, das ich mir ein wenig zu Gemüte führen werde. Aber das braucht halt alles seine Zeit.
Der Grundcode für den Sensor stammt aus dem verlinkten Beispiel von Toradex (siehe Eröffnungspost), dem Sensorhersteller.
Ich versuche es so anzupassen, dass es den von mir gewünschten Zweck erfüllt.
Und dabei nehme ich so viele Stolperfallen mit, wie es nur geht
-
Tipp: Erst programmieren lernen, dann das Programm anpassen. Glaub mir, das ist die wesentlich schnellere Methode und das Ergebnis ist am Ende auch viel besser. Denk nur, wie weit du in deinem Buch schon wärst, wenn du die letzten drei Tage nicht mit unbeholfener Fehlersuche verbracht hättest.
Such dir erst einmal einfache Probleme. Lerne an diesen die Grundlagen, die wichtigsten Strukturen und wie man Fehler findet. Wenn du das erst einmal drauf hast, dann funktioniert es auch bei scheinbar schwierigen Problemen ganz von alleine. Komplexe Probleme sind nämlich gar nicht schwer, sie bestehen bloß aus vielen einfachen Problemen
. Wenn du diese erst einmal selbstständig, sicher und gut angehen kannst, dann ist das komplexe Problem bloß eine Frage der mehrfachen Anwendung. Wenn du hingegen gleich das schwierige Problem angehst, erschlägt es dich, da du noch nicht gelernt hast, in kleinen, einfachen Problemstellungen zu denken.
Gutes Beispiel ist dein for-switch. Ein Antipattern über das hier jeder heimlich lacht. Aber da du keine Übung in einfachen Ablaufplänen hast, weißt du weder, wie es besser geht, noch was die anderen Forennutzer daran so komisch finden.
configure, make, make install ist übrigens auch wieder kein C, sondern eine allgemein übliche Art und Weise, Software vom Quellcode an zu verteilen:
Google: configure make make install
-
Ja, das stimmt, mein Problem ist eine Ansammlung von vielen kleinen Problemen, aber dennoch möchte ich mich da durch beißen.
Versuch macht kluch, wie man so schön sagt@Furble:
Ich bin positiv überrascht. Klein, smart, funktioniert.
Einen Haken hat die Sache jedoch.
Der erste Messdurchlauf spuckt ne Reihe von 0.000000 aus.
Danach funktioneirt das aber problemlos.Als nächstes möchte ich das Array auswerten und Ausreißer rausschmeißen.
Mein Plan ist:
Das Array mit "qsort" (http://stackoverflow.com/questions/1787996/c-library-function-to-do-sort) auf- oder absteigend sortieren.Danach nehme ich einen Wert aus der Mitte des Arrays und vergleiche alle Werte des kompletten Arrays, ob sie eine Abweichung haben, die größer als ein gewisser Betrag ist. Da ich einen maximalen Anteill an Ausreißern von 10% habe, sollte ich hiermit gut arbeiten können.
Gibt es eine empfehlenswertere Methode um das Array zu sortieren, als das, was ich auf Stackoverflow gefunden habe?
Außerdem habe ich mich mal mit dem Hersteller des Sensors in Verbindung gesetzt, da der Sensor auch ein Temperatursignal liefert.
Ich wollte wissen, ob ich dies auch abgreifen kann, da die OakLibary standardmäßig lediglich die Werte
Frame[s],Acceleration[m/s²],Zenith [rad],Azimuth[rad] liefert.Daraufhin wurde ich auf das Datenblatt des intern verwendeten "SCA3000-D01" verwiesen.
Das Datenblatt des kompletten USB-Geräts wäre hier: http://docs.toradex.com/100095-oak-tilt-inclination-datasheet.pdf
Und das Datenblatt des verwendeten ICs auf der Platine befindet sich hier:
https://www.sparkfun.com/datasheets/Sensors/Accelerometer/SCA3000-D01.pdfLaut OakTilt-Datasheet:
3.2.7 Direct access to Sensor Registers This command allow to directly read and write registers of the sensor. This can be used for example to change the measurement mode (sensor bandwidth). Byte# Content GnS: 0 1 2 3 4 5 GnS 0x03 0x01 RegAddr 0x00 RegValue 0 = Set 1 = Get RegAddr: Register Address (refer to the SCA3000 datasheet for details) RegValue: Register content (refer to the SCA3000 datasheet for details)
Laut Sensor-IC-Datasheet hat der verwendete SCA3000-D01 auch einen "Temperature output".
Hat hier vielleicht jemand eine Idee, wie ich nun die ausgewertete Temperatur abgreifen kann?
Im Datenblatt finde ich leider keine Infos, die mir in irgendeiner Weise einen Ansatz zum Googeln liefern.PS: Ists vielleicht sinnvoller, wenn ich für diese zwei Problemchen nen neuen Threat aufmache? Ich weiß noch nicht so recht, wie ihr das hier im Board bevorzugt handhabt
-
Cysign schrieb:
Ich bin positiv überrascht. Klein, smart, funktioniert.
Einen Haken hat die Sache jedoch.
Der erste Messdurchlauf spuckt ne Reihe von 0.000000 aus.
Danach funktioneirt das aber problemlos.Dafür wird es sicher einen Grund geben - k.A. wo und wie Du jetzt eine Ausgabe gebaut hast.
Evtl. poste nochmal den aktuellen Stand des gesamten Programms.
Das ist aber auch schon alles, was von Deinen Problemen noch in diesen Thread gehört.Cysign schrieb:
Als nächstes möchte ich das Array auswerten und Ausreißer rausschmeißen.
Mein Plan ist:
Das Array mit "qsort" (http://stackoverflow.com/questions/1787996/c-library-function-to-do-sort) auf- oder absteigend sortieren.Danach nehme ich einen Wert aus der Mitte des Arrays und vergleiche alle Werte des kompletten Arrays, ob sie eine Abweichung haben, die größer als ein gewisser Betrag ist. Da ich einen maximalen Anteill an Ausreißern von 10% habe, sollte ich hiermit gut arbeiten können.
Gibt es eine empfehlenswertere Methode um das Array zu sortieren, als das, was ich auf Stackoverflow gefunden habe?
Meiner Meinung nach solltest Du Dir die Möglichkeiten zur Sortierung von C++ ansehen.
Wenn Du in Deinem Kontext dazu Fragen hast, frag bitte im C++-Bereich - am Besten Du hast dann auch gleich ein Array mit Beispieldaten zur Hand.Zur Sache mit dem Datenblatt/Hardware usw. gilt das gleiche: richtiges Unterforum suchen, dort posten.