Как использовать хроно сон без лагов?

Я только новичок в С++, мне нужно нарисовать объект на существующих четырех маркерах с задержкой между каждым маркером и другим, я пытался использовать Chrono_sleep_until, но это заставляет мою программу отставать, и даже объект мгновенно появляется и исчезает на втором маркере, я знаю, что что-то не так, но не могу догадаться, что это может быть, любая помощь?

std::vector<int> ids;
    std::vector<std::vector<cv::Point2f> > corners;
    cv::aruco::detectMarkers(image, marker_dict, corners, ids);

    // Draw markers using opencv tool
    cv::aruco::drawDetectedMarkers(mid, corners, ids);

    // Draw markers custom
    for (size_t i = 0; i < corners.size(); ++i)
    {

        // Convert to integer ponits
        int num = static_cast<int>(corners[i].size());
        std::vector<cv::Point> points;
        for (size_t j = 0; j < corners[i].size(); ++j)
            points.push_back(cv::Point(static_cast<int>(corners[i][j].x), static_cast<int>(corners[i][j].y)));
        const cv::Point* pts = &(points[0]);


        // Draw


        
        if (ids.at(i) == 32) {
            cv::fillPoly(right, &pts, &num, 1, cv::Scalar(255, 0, 0));

        }
        std::chrono::system_clock::time_point timePoint = std::chrono::system_clock::now() + std::chrono::seconds(2);
        std::this_thread::sleep_until(timePoint);
    
    
            if (ids.at(i) == 45) {
            
                cv::fillPoly(right, &pts, &num, 1, cv::Scalar(255, 0, 0));
                break;
            
        
            }

person M_Mohy    schedule 30.06.2020    source источник
comment
sleep_until работает точно только тогда, когда вы определяете время окончания перед циклом и увеличиваете его внутри цикла - в противном случае время будет дрейфовать. Это то, что тебе надо? stackoverflow.com/questions/39987806/accurate-sampling- in-c/   -  person Galik    schedule 30.06.2020
comment
@Galik Я так и сделал, и задержки больше нет, но второй маркер с id 45 не ждет определенное время, а появляется, исчезает, постоянно мигая.   -  person M_Mohy    schedule 30.06.2020


Ответы (1)


Sleep отлично подходит для PoC и быстрых исправлений для небольших проблем, но для большинства серьезных проектов вы можете рассмотреть возможность использования таймера, подождать, пока таймер не достигнет вашей задержки, а затем продолжить. Тогда остальная часть вашего кода все еще выполняется, и ни один поток не спит.

Это слишком упрощенное решение, просто чтобы дать вам представление, оно вызовет DrawB() через 1 секунду после вызова DrawA() без сна.

#include <windows.h>
#include <iostream>
#include <chrono>

using Clock = std::chrono::steady_clock;
std::chrono::time_point<std::chrono::steady_clock> start, now;
std::chrono::milliseconds duration;

bool bDoDrawA = true;
bool bDoDrawB = false;

void DrawA()
{
    std::cout << "DrawA()" << std::endl;

    bDoDrawB = true;
    bDoDrawA = false;
}

void DrawB()
{
    std::cout << "DrawB()" << std::endl;

    bDoDrawB = false;
    bDoDrawA = true;
    start = Clock::now();
}

int main()
{
    while (true)
    {
        if (bDoDrawA)
        {
            DrawA();
        }
        
        if (bDoDrawB)
        {
            now = Clock::now();
            duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - start);

            if (duration.count() >= 2000)
            {
                DrawB();
            }
        }
    }

    return 0;
}

person GuidedHacking    schedule 02.07.2020