crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

AD
  опции профиля:
сообщение 11.6.2009, 17:56
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


В какой-то момент стартанули поток, процесс, таймер (не столь важно). Этот момент времени запомнили. Через какие-то промежутки времени берем текущее время. Узнаем разность. Но вопрос в том, как получить оставшееся время?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
igor_bogomolov
  опции профиля:
сообщение 16.6.2009, 11:03
Сообщение #2


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(Игорь)
А я вот совершенно не уверен (по тому коду, что сейчас есть). Что произойдет, когда int secs станет отрицательным. t = t.addSecs(secs) останется инициализированным нулями? Я не проверял такого поведения.
Т.е. я не говорил, что это плохо, а только то что, не знаю как данный код отработает. Теперь буду знать, что addSecs может принимать отрицательное значение, и коректно его отрабатывать.


Тагда остается проблемма если твой прожектор должен крутиться больше суток :)
Если конечно такое возможно

Сообщение отредактировал igor_bogomolov - 16.6.2009, 11:05
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 16.6.2009, 11:38
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(igor_bogomolov @ 16.6.2009, 12:03) *
Тагда остается проблемма если твой прожектор должен крутиться больше суток :)
Если конечно такое возможно

Ну это не проблема! :) Больше чем 24 часа нельзя задать. SpinBox для задания времени ограничил специально! :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 16.6.2009, 14:23
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Никак не пойму, почему таймер не срабатывает. Делаю теперь так, учтя все советы:
Thread
/// Класс потока - вращение вокруг осей заданное количество времени - длительное вращение
class ContinueRotation: public QThread
{
    Q_OBJECT

private:
    INFO_TO_EXTERN_DEVICE inf_to_ed_packet;        ///< пакет данных внешнему устройству в режиме авто управления
    INFO_FROM_EXTERN_DEVICE inf_from_ed_packet;    ///< пакет данных от внешнего устройства в режиме авто управления
    const int MAXBYTES;                            ///< константа максимального количества байт
    ImitatorTSL* imitTsl;                        ///< указатель на класс главного окна
    QTime _time;                                ///< счетчик времени вращения прожектора
    QTime starting_time, finished_time;            ///< время начала и окончания отсчета
    QMutex mutex;                                ///< мьютекс блокировки работы
    QTimer _working_spotlight;                    ///< таймер работы прожектора

private:
    void readAzimuth(int& geted_azimuth, double limit);
    void readAngleElevation(int& geted_angle_elev, double limit);
    void originPosition();
    void readAngles();
    void timerTicks();

protected:
    virtual void run();

signals:
    void _timeout(QTime);

private slots:
    void workSpotlight();

public:
    ContinueRotation(QObject *parent);
    ~ContinueRotation();
    void tsl(ImitatorTSL* im) { imitTsl = im; }
    ImitatorTSL* tsl() const { return imitTsl; }
    INFO_TO_EXTERN_DEVICE continueControl();
    void fromExternalDevice(INFO_FROM_EXTERN_DEVICE& mp);
    void setToEDInfo(const INFO_TO_EXTERN_DEVICE& ed) { inf_to_ed_packet = ed; }
    void setFromEDInfo(const INFO_FROM_EXTERN_DEVICE& ed) { inf_from_ed_packet = ed; }
    INFO_TO_EXTERN_DEVICE toEDInfo() { return inf_to_ed_packet; }
    INFO_FROM_EXTERN_DEVICE fromEDInfo() { return inf_from_ed_packet; }
    QTime elapsedTime() const { return _time; }
    QTime startingTime() const { return starting_time; }
    void setTime(const QTime& t) { _time = t; }
    void setTime(const int h, const int m) { _time.setHMS(h, m, 0, 0); }
    void setStartingTime(const QTime& t);
};

ContinueRotation::ContinueRotation(QObject *parent): QThread(parent), MAXBYTES(256), imitTsl(0),
                    inf_to_ed_packet(INFO_TO_EXTERN_DEVICE()), inf_from_ed_packet(INFO_FROM_EXTERN_DEVICE())
{}

ContinueRotation::~ContinueRotation() {}

/// Получение азимута
void ContinueRotation::readAzimuth(int& geted_azimuth, double limit)
{
    if(!imitTsl) return;
    while(geted_azimuth < ((limit - 1.5) * 10) || geted_azimuth > ((limit + 1.5) * 10))
    {
        imitTsl -> readFromCtrlPage();
        geted_azimuth = VALFROMBYTES(inf_from_ed_packet.high_azim, inf_from_ed_packet.low_azim);
    }
}

/// Получение угла места
void ContinueRotation::readAngleElevation(int& geted_angle_elev, double limit)
{
    if(!imitTsl) return;
    while(geted_angle_elev < ((limit - 1.5) * 10) || geted_angle_elev > ((limit + 1.5) * 10))
    {
        imitTsl -> readFromCtrlPage();
        geted_angle_elev = VALFROMBYTES(inf_from_ed_packet.high_angle_elev, inf_from_ed_packet.low_angle_elev);
    }
}

/// Чтение углов
void ContinueRotation::readAngles()
{
    if(!imitTsl) return;
    int geted_azimuth, geted_angle_elev;
    QTime begining_time(QTime::currentTime());
    do
    {
        imitTsl -> readFromCtrlPage();
        geted_azimuth = VALFROMBYTES(inf_from_ed_packet.high_azim, inf_from_ed_packet.low_azim);
        geted_angle_elev = VALFROMBYTES(inf_from_ed_packet.high_angle_elev, inf_from_ed_packet.low_angle_elev);
        int secs = begining_time.secsTo(QTime::currentTime());
        if(secs > 10) break; 
    } while(geted_azimuth < 0 || geted_azimuth > 3 || geted_angle_elev < 0 || geted_angle_elev > 3);
}

/// Возвращение пакета с данными от внешнего устройства в режиме автоматического управления
INFO_TO_EXTERN_DEVICE ContinueRotation::continueControl()
{
    BYTE sum = 0;
    BYTE* ptr = (BYTE*) (&inf_to_ed_packet);
    for(register int i=0; i<(sizeof(inf_to_ed_packet) - 1); ++i) sum += ptr[i];
    inf_to_ed_packet.checksum = MAXBYTES - sum;
    return inf_to_ed_packet;
}

/// Установка пакета данных от внешнего управления в автоматической режиме работы
void ContinueRotation::fromExternalDevice(INFO_FROM_EXTERN_DEVICE& mp)
{
    BYTE sum = 0;
    BYTE* ptr = (BYTE*) (&mp);
    for(register int i=0; i<(sizeof(mp) - 1); ++i) sum += ptr[i];
    if((MAXBYTES - sum) == mp.checksum)
        inf_from_ed_packet = mp;
}

/// Установка времен начала и окончания работы прожектора
void ContinueRotation::setStartingTime(const QTime& t)
{
    starting_time = t;
    finished_time.setHMS(starting_time.hour() + _time.hour(), starting_time.minute() + _time.minute(),
                         starting_time.second() + _time.second(), starting_time.msec() + _time.msec());
}

/// Перемещение прожектора в исходную позицию
void ContinueRotation::originPosition()
{
    int geted_azimuth = VALFROMBYTES(inf_from_ed_packet.high_azim, inf_from_ed_packet.low_azim);
    int geted_angle_elev = VALFROMBYTES(inf_from_ed_packet.high_angle_elev, inf_from_ed_packet.low_angle_elev);
    if(geted_azimuth || geted_angle_elev)
    {
        int azimuth = 0, angle_elevation = 0;
        inf_to_ed_packet.low_azim = LOWBYTE(azimuth);
        inf_to_ed_packet.high_azim = HIGHBYTE(azimuth);
        inf_to_ed_packet.low_angle_elev = LOWBYTE(angle_elevation);
        inf_to_ed_packet.high_angle_elev = HIGHBYTE(angle_elevation);
        if(imitTsl) imitTsl -> writeFromCtrlContinuous();
    }
}

/// Отсчет оставшегося времени работы прожектора
void ContinueRotation::timerTicks()
{
    int secs = QTime::currentTime().secsTo(finished_time);
    QTime t;    t = t.addSecs(secs);
    int el_t = t.hour() * 60 * 60 * 1000 + t.minute() * 60 * 1000 + t.second() * 1000 + t.msec();
    int _t = _time.hour() * 60 * 60 * 1000 + _time.minute() * 60 * 1000 + _time.second() * 1000 + _time.msec();
    float diff = _t - el_t;
    mutex.lock();
    _time = t;
    if(fabs(diff) >= 1000) emit _timeout(_time);
    mutex.unlock();
}

/// Слот работы прожектора - вращения в обеих плоскостях
void ContinueRotation::workSpotlight()
{
    timerTicks();

    int geted_angle_elev = -1, geted_azimuth = -1;

    /// Перемещение вниз и вправо до упора
    int angle_elevation = -110 * 10, azimuth = 172 * 10;
    inf_to_ed_packet.low_angle_elev = LOWBYTE(angle_elevation);
    inf_to_ed_packet.high_angle_elev = HIGHBYTE(angle_elevation);
    inf_to_ed_packet.low_azim = LOWBYTE(azimuth);
    inf_to_ed_packet.high_azim = HIGHBYTE(azimuth);
    if(imitTsl) imitTsl -> writeFromCtrlContinuous();
    readAngleElevation(geted_angle_elev, (double)angle_elevation / 10.);
    readAzimuth(geted_azimuth, (double) azimuth / 10.);

    timerTicks();

    /// Перемещение вверх и влево до упора
    angle_elevation = 10 * 10;        azimuth = -172 * 10;
    inf_to_ed_packet.low_angle_elev = LOWBYTE(angle_elevation);
    inf_to_ed_packet.high_angle_elev = HIGHBYTE(angle_elevation);
    inf_to_ed_packet.low_azim = LOWBYTE(azimuth);
    inf_to_ed_packet.high_azim = HIGHBYTE(azimuth);
    if(imitTsl) imitTsl -> writeFromCtrlContinuous();
    readAngleElevation(geted_angle_elev, (double)angle_elevation / 10.);
    readAzimuth(geted_azimuth, (double)azimuth / 10.);

    timerTicks();

    /// Возврат в исходное положение
    angle_elevation = 0;        azimuth = 0;
    inf_to_ed_packet.low_angle_elev = LOWBYTE(angle_elevation);
    inf_to_ed_packet.high_angle_elev = HIGHBYTE(angle_elevation);
    inf_to_ed_packet.low_azim = LOWBYTE(azimuth);
    inf_to_ed_packet.high_azim = HIGHBYTE(azimuth);
    if(imitTsl) imitTsl -> writeFromCtrlContinuous();

    timerTicks();
}

/// Запуск потока вращения в обеих плоскостях длительный промежуток времени
void ContinueRotation::run()
{
    timerTicks();
    originPosition();
    readAngles();

    connect(&_working_spotlight, SIGNAL(timeout()), this, SLOT(workSpotlight()));
    const int working_time = 60 * 1000;
    _working_spotlight.start(working_time);

    while(QTime::currentTime() <= finished_time)
    {
        timerTicks();
        msleep(1000);
    }
    if(QTime::currentTime() > finished_time && _working_spotlight.isActive())
        _working_spotlight.stop();
}


Думаю, если есть неточности в коде, то они кроются в функции run():
/// Запуск потока вращения в обеих плоскостях длительный промежуток времени
void ContinueRotation::run()
{
    timerTicks();
    originPosition();
    readAngles();

    connect(&_working_spotlight, SIGNAL(timeout()), this, SLOT(workSpotlight()));
    const int working_time = 60 * 1000;
    _working_spotlight.start(working_time);

    while(QTime::currentTime() <= finished_time)
    {
        timerTicks();
        msleep(1000);
    }
    if(QTime::currentTime() > finished_time && _working_spotlight.isActive())
        _working_spotlight.stop();
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме
- AD   остаток времени в QTime   11.6.2009, 17:56
- - Litkevich Yuriy   Цитата(AD @ 11.6.2009, 21:56) оставшееся ...   11.6.2009, 18:03
|- - AD   А ну да... не так выразился... Задали какое-то вр...   11.6.2009, 18:12
- - Litkevich Yuriy   Запомнить время начала и посчитать сколько должно ...   11.6.2009, 18:47
|- - AD   Цитата(Litkevich Yuriy @ 11.6.2009, 19:47...   11.6.2009, 21:48
|- - AD   Не могу понять, как сделать, чтобы во время отсчет...   15.6.2009, 12:33
- - SABROG   Поправь меня, если я не прав, но тут посылается це...   15.6.2009, 12:59
|- - AD   Цитата(SABROG @ 15.6.2009, 13:59) Поправь...   15.6.2009, 13:16
- - SABROG   Цитата(AD @ 15.6.2009, 14:16) Ну а как то...   15.6.2009, 13:31
- - kwisp   Цитата(AD @ 15.6.2009, 14:16) Ну как заст...   15.6.2009, 13:46
|- - AD   Цитата(kwisp @ 15.6.2009, 14:46) была так...   15.6.2009, 14:26
- - igor_bogomolov   Цитата(AD)/// Запуск потока вращения в обеих плоск...   15.6.2009, 14:45
|- - AD   Цитата(igor_bogomolov @ 15.6.2009, 15:45)...   15.6.2009, 15:04
- - kwisp   AD, значит я чего-то не допонял.   15.6.2009, 14:50
- - igor_bogomolov   Цитата(kwisp @ 15.6.2009, 15:50) значит я...   15.6.2009, 14:56
- - igor_bogomolov   Цитата(AD @ 15.6.2009, 13:33) QTime start...   15.6.2009, 15:08
|- - AD   Цитата(igor_bogomolov @ 15.6.2009, 16:08)...   15.6.2009, 15:17
- - igor_bogomolov   Цитата(AD @ 15.6.2009, 16:04) 1) Да. Попр...   15.6.2009, 15:23
|- - AD   Цитата(igor_bogomolov @ 15.6.2009, 16:23)...   15.6.2009, 15:31
- - kwisp   Цитата(kwisp @ 15.6.2009, 15:50) значит я...   15.6.2009, 15:33
|- - AD   Задается определенное время, например 15 минут или...   15.6.2009, 15:57
- - SABROG   Таймер и другой поток необходимы в ситуации, когда...   15.6.2009, 15:44
- - igor_bogomolov   Цитата(AD @ 15.6.2009, 16:17) Такую ситуа...   15.6.2009, 17:44
|- - AD   Цитата(igor_bogomolov @ 15.6.2009, 18:44)...   15.6.2009, 18:29
- - kwisp   Цитата(AD @ 15.6.2009, 19:29) Мне необход...   15.6.2009, 20:50
- - igor_bogomolov   Цитата(AD @ 15.6.2009, 19:29) Мне необход...   15.6.2009, 22:43
|- - AD   Цитата(igor_bogomolov @ 15.6.2009, 23:43)...   16.6.2009, 8:44
|- - AD   Цитата(igor_bogomolov @ 15.6.2009, 23:43)...   17.6.2009, 9:29
- - Litkevich Yuriy   Цитата(AD @ 16.6.2009, 12:44) или же в са...   16.6.2009, 8:55
|- - AD   вызвать сигнал, который ассоциирую со слотом, выпо...   16.6.2009, 9:56
- - igor_bogomolov   Цитата(Игорь)А я вот совершенно не уверен (по тому...   16.6.2009, 11:03
|- - AD   Цитата(igor_bogomolov @ 16.6.2009, 12:03)...   16.6.2009, 11:38
|- - AD   Никак не пойму, почему таймер не срабатывает. Дела...   16.6.2009, 14:23
- - igor_bogomolov   Цитата(AD @ 17.6.2009, 10:29) Это насколь...   17.6.2009, 11:30
|- - AD   Цитата(igor_bogomolov @ 17.6.2009, 12:30)...   17.6.2009, 12:08
- - AD   igor_bogomolov, видимо, я так не смогу сам определ...   17.6.2009, 15:52
- - AD   Ну разобрался, наконец-то! Вот окончательная ...   17.6.2009, 17:50


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 5.6.2025, 19:21