Pro Minute x mal Schleife ausführen lassen



  • Hey Leute,
    ich arbeite mit einer FlyCapture2-Kamera https://www.ptgrey.com/flycapture-sdk.
    Die Kamera soll jede Minute 20 Mal ein Bild machen. Das Problem ist, dass es schon ein vorgefertigtes Skript ist. Welches so ausgebaut ist, dass es beim ausführen beliebig viele Bilder macht. Die Frage, die sich mir stellt ist, wo füge ich die Schleife ein ?
    Ich schicke den wichtigen Teil des Skripts hier rein:
    int RunSingleCamera(PGRGuid guid)

    {
    const int k_numImages = 10;

    Error error;    
    
    // Connect to a camera
    

    Camera cam;
    error = cam.Connect(&guid);
    if (error != PGRERROR_OK)
    {
    PrintError(error);
    return -1;
    }

    // Get the camera information
    CameraInfo camInfo;
    error = cam.GetCameraInfo(&camInfo);
    if (error != PGRERROR_OK)
    {
        PrintError(error);
        return -1;
    }
    
    PrintCameraInfo(&camInfo);
    
    // Get the camera configuration
    FC2Config config;
    error = cam.GetConfiguration(&config);
    if (error != PGRERROR_OK)
    {
        PrintError(error);
        return -1;
    }
    
    // Set the number of driver buffers used to 10.
    config.numBuffers = 10;
    
    // Set the camera configuration
    error = cam.SetConfiguration(&config);
    if (error != PGRERROR_OK)
    {
        PrintError(error);
        return -1;
    }
    
    // Start capturing images
    error = cam.StartCapture();
    if (error != PGRERROR_OK)
    {
        PrintError(error);
        return -1;
    }
    
    Image rawImage;
    for (int imageCnt = 1; imageCnt < k_numImages; imageCnt++)
    {
        // Retrieve an image
        error = cam.RetrieveBuffer(&rawImage);
        if (error != PGRERROR_OK)
        {
            PrintError(error);
            continue;
        }
    

    Wo sollte ich die Schleife einfügen?

    Freue mich über jede Hilfe!



  • Ganz aussen rundrum machst du die Schleife und rufst darin die Funktion mit immer einem Bild auf, wenn die gewünschte Zeit (3s) vorbei ist.



  • @Manni23 sagte in Pro Minute x mal Schleife ausführen lassen:

    StartCapture()

    Also die Funktion in einer Schleife ausführen lassen ?
    Und weißt du wie ich am besten den Timer umsetze ?



  • Am besten überlässt man das dem Betriebssystem, damit der Thread schön schlafen kann bis dahin. Heisst bei C++ konkret, das du eine passenden Bibliothek dafür benutzen würdest.



  • Naja ab C++11 gibt's this_thread::sleep_for bzw. this_thread::sleep_until.



  • #include<stdlib.h>
    #include<string.h>
    #include<time.h>

    using namespace std;

    int main()
    {

    time_t rawtime;
    struct tm * timeinfo;
    char buffer [80];

    time (&rawtime);
    timeinfo = localtime (&rawtime);

    strftime (buffer,80,"%d.%m.%y-%H:%M",timeinfo);

    }

    Ich hab nun eine Möglichkeit gefunden die Uhrzeit auszugeben.
    Jedoch weiß ich nicht, wie ich der Schleife mitteilen soll, das zum Beispiel alle 10 Sekunden die Funktion ausgeführt wird.
    Ich habe daran Gedacht als Bedingung zu sagen, dass immer wenn eine Minute durch 10 geteilt wird und eine ganze zahl rauskommt, die Schleife ausgeführt wird.
    Kann jemand sagen, wie ich das umsetzen kann ?


  • Mod

    Hast du eine einzige der Antworten hier im Thread gelesen? Dein Code hat keinen erkennbaren Zusammenhang zu irgendetwas, was gesagt wurde, sondern sieht eher nach einem gegoogelten Beispiel aus, wie man in C (nicht einmal C++!) die Uhrzeit ausgibt. Was der totale Holzweg ist. Niemand im Thread hat irgendetwas von der Uhrzeit oder ihrer Ausgabe gesagt.



  • @SeppJ Das stimmt so nicht, mein Code gibt mir in C++ die Uhrzeit aus. Damit speicher ich zum Beispiel die Fotos unter dieser Uhrzeit an, also Aufnahme 1 - 19.11.2018-19:56 usw. Und mir ist bewusst was die Leute geschrieben haben, jedoch dachte ich man könnte vielleicht dies nutzen für mein Problem. Programmiere zum ersten Mal im Leben C++ also bitte ich um ein wenig Nachsicht. Wenn jemand mir das mit sleep erklären könnte wäre ich sehr dankbar, kann leider nichts brauchbares im Internet finden


  • Mod

    Ja, aber wie erwartest du denn, wie du dein Problem löst, wenn du die Anleitungen zur Lösung deines Problems nicht befolgst?! Bloß weil du die Anleitungen nicht verstehst, heißt das ja nicht, dass die nicht der richtige Weg wären.

    Dass dein C-Code auch mit C++ übersetzbar ist, heißt nicht, dass er C++ wäre.

    Da dein C-Code offensichtlich ein Beispiel aus einer C-Referenz ist (Das ist begrüßenswerte Eigeninitiative, bitte nicht falsch verstehen!), wie wäre es, stattdessen mal die genannten Stichworte in einer C++-Referenz zu suchen?



  • Strftime ist aber eine C++ Referenz soweit ich weiß.
    http://www.cplusplus.com/reference/thread/this_thread/sleep_until/
    Jedenfalls wurde das ja vorgeschlagen, also sollte ich das nutzen.
    Die Frage ist, ab welchem Punkt setzt diese Referenz fest, wann der Thread wieder ausgeführt wird. Und ist möglich, dies mit einer while-Schleife zu kombinieren ?



  • sleep_untilschläft bis zu einem absoluten Zeitpunkt. Wenn du eine Funktion x-mal pro Minute ausführen willst ist die Zeitspanne, die der Thread schlafen soll, 60/x Sekunden. Also nimmst du den aktuellen Zeitstempel und addierst die Schlafperiode dazu und hast den Aufwachzeitpunkt.
    Besser ist vllt sleep_for, da kannst du direkt angeben, wie lange der Thread schlafen soll ohne den Aufwachzeitpunkt ausrechnen zu müssen.



  • Die Initialisierung solltest du nur am Anfang ausführen, das Schießen von Fots dann in einer Schleife. Wenn man es zusammenfasst, könnte es so aussehen (da stecken vermutlich Fehler drin, da ich es wegen der fehlenden Bibliothek auch gar nicht kompilieren könnte):

    bool initCam(Camera& cam, const PGRGuid& guid)
    {
    	// Connect to a camera
    	Error error = cam.Connect(&guid);
    	if (error != PGRERROR_OK)
    	{
    		PrintError(error);
    		return false;
    	}
    	CameraInfo camInfo;
    	error = cam.GetCameraInfo(&camInfo);
    	if (error != PGRERROR_OK)
    	{
    		PrintError(error);
    		return false;
    	}
    	PrintCameraInfo(&camInfo);
    	// Get the camera configuration
    	FC2Config config;
    	error = cam.GetConfiguration(&config);
    	if (error != PGRERROR_OK)
    	{
    		PrintError(error);
    		return false;
    	}
    	// Set the number of driver buffers used to 1.
    	config.numBuffers = 1;
    	error = cam.SetConfiguration(&config);
    	if (error != PGRERROR_OK)
    	{
    		PrintError(error);
    		return false;
    	}
    	return true;
    }
    
    bool capture(Camera& cam, Image& rawImage)
    {
    	return cam.RetrieveBuffer(&rawImage)==PGRERROR_OK;
    }
    
    #include <chrono>
    #include <thread>
    
    int main()
    {
    	using namespace std::chrono_literals;
    	Camera camera;
    	// PGRGuid guid=...;
    	if(!initCam(camera, guid))
    		return -1;
    
    	Image rawImage;
    	while(/*!Abbruchbedingung*/)
    	{
    		if(capture(cam, rawImage))
    		{
    			// rawImage verarbeiten
    		}
    		std::this_thread::sleep_for(3s);
    		// oder sonst auch direkt eine OS-Funktion wie: Sleep(3000);
    	}
    }
    

    Noch besser wäre es natürlich, die gesamte Funktionalität in einer Klasse zu kapseln. Wenn man es genau machen möchte, sollte auch die Zeit des letzten Captures und der Verarbeitung in das nächste Sleep mit einfließen.
    Zu den Dateinamen: 20 Bilder/min würden 1200 Bilder/h und knapp 30.000 Bilder pro Tag sein. Es kommt drauf an, was du damit machen möchtest, aber besser wäre es sowieso, den Zeitstempel direkt in das Bild zu schreiben und dann nur den Dateinamen aus dem letzten Tag/Stunde/Minute zusammenzusetzen und ältere Dateien zu überschreiben.



  • @yahendrik danke für deine Antwort, hab es so in etwa gemacht. Anscheinend muss ich den compiler in c++11 laufen lassen, hab schon mehrfach gegoogelt und rausgefunden, dass ich -std=c++11 irgendwo integrieren muss. Jedoch werde ich nicht schlauer. Ich habe einen MakeFile und halt mein .cpp File aber wohin kommt -std=c+11 ?



  • Schau mal, ob es in dem Makefile schon einen Eintrag für CFLAGS (bzw. CXXFLAGS) gibt und dort fügst du dann noch -std=c+11 hinzu.



  • @Th69

    Intermediate object files

    ${OBJ}: ${ODIR}/%.o : {SDIR}/%.cpp @{MKDIR} ${ODIR}
    ${CXX} ${CXXFLAGS -std=c++11} ${LINUX_DEFINES} ${INC} -Wall -c $< -o $@

    hab dort -std=c++11 eingefügt, passt das so von der syntax ?



  • @Manni23 sagte in Pro Minute x mal Schleife ausführen lassen:

    @Th69

    Intermediate object files

    ${OBJ}: ${ODIR}/%.o : {SDIR}/%.cpp @{MKDIR} ${ODIR}
    ${CXX} ${CXXFLAGS -std=c++11} ${LINUX_DEFINES} ${INC} -Wall -c $< -o $@

    hab dort -std=c++11 eingefügt, passt das so von der syntax ?

    Du könntest das "-std=c++11" auch in deine CXXFLAGS-Variable einfügen. Die "${...}"-Sachen lässt man normalerweise wie sie sind. Ersatzweise kann du das auch einfach hinter "-Wall" einfügen.
    Auf jeden Fall ist es wichtig, dass du verstehst was dein Makefile tut.



  • @It0101 Der MakeFile kompiliert das ganze Programm, wie ich das verstanden habe.
    Und ich habe "-std=c++11" hinter "-Wall" eingefügt, scheint jetzt zu funktionieren. Jedoch kann ich nicht ganz nachvollziehen, wieso ich auf C++11 downgraden muss um diese Funktionen wie sleep_for zu benutzen ?



  • Nicht downgraden. Da wird wohl als default C++03 verwendet werden.



  • @Manni23 sagte in Pro Minute x mal Schleife ausführen lassen:

    @It0101 Der MakeFile kompiliert das ganze Programm, wie ich das verstanden habe.

    Ich meinte damit, dass du verstehst, was die ganzen "${}"-Variablen tun, wie man Warnungen, Defines und andere Dinge dem Buildprozess hinzufügt usw.
    Keine Angst vor Makefiles! Das ist alles kein Hexenwerk.



  • @It0101 werde ich auf jeden Fall noch machen, jedoch funktioniert es ja soweit.
    Das Problem ist, dass er alles ausführt ohne Fotos zu machen.
    Sprich er führt einmal die Schleife aus, wartet die 2 Sekunden und dann bricht er ab.

    Hier einmal die Schleife für diese 2 Sekunden und einmal das Standard Skript.
    Vielleicht erkennt jemand den Fehler ?

    // Start capturing images

    while(1)
    {
    error = cam.StartCapture();
    if (error != PGRERROR_OK)
    {
        PrintError(error);
        return -1;
    }
    std::this_thread::sleep_for(std::chrono::seconds(2));
    
    }
    

    // Start capturing images
    error = cam.StartCapture();
    if (error != PGRERROR_OK)
    {
    PrintError(error);
    return -1;
    }


Anmelden zum Antworten