BRE |
Дата 30.11.2009, 18:43 |
|
Цитата(AD @ 30.11.2009, 18:38) Надо как-то по-другому выкручиваться. Попробуй делать два таймера, по одном поворачивать, по другому читать. И все будет Ok.
|
AD |
Дата 30.11.2009, 18:38 |
|
Цитата(Litkevich Yuriy @ 30.11.2009, 18:29) Для обсуждения идей создай отдельную тему. Проблема: "Работа таймера в параллельном потоке" решена? Можно сказать, что да. Таймер, к сожалению, тут не подходит. Надо как-то по-другому выкручиваться. Можешь закрыть. А код выкладывал, для того, чтобы это не выглядело голословно, как раз таки! |
Litkevich Yuriy |
Дата 30.11.2009, 18:29 |
|
Цитата(AD @ 30.11.2009, 21:24) Идея, а не код. тогда зачем ты код выкладываешь?
Для обсуждения идей создай отдельную тему. Проблема: "Работа таймера в параллельном потоке" решена? |
BRE |
Дата 30.11.2009, 18:29 |
|
Что делает этот код?
for(int timer_count=0; QTime::currentTime()<=finished_time;) { if(_finished) break; timerTicks(); if(timer_count == 60) timer_count = 0; if(!timer_count) emit working_light(); ++timer_count; }
Может проще запустить еще один таймер, который раз в секунду будет дергать working_light и проверять, если все повернулось останавливать таймер или всю нить.
|
AD |
Дата 30.11.2009, 18:24 |
|
Цитата(Litkevich Yuriy @ 30.11.2009, 18:23) AD, ты уже в который раз спускаешся до подробностей прикладного кода, складывается такое впечатление, что ты хочешь чтобы за тебя программу написали. Нет. Мне бы идею подсказать, как это сделать. Идея, а не код. |
Litkevich Yuriy |
Дата 30.11.2009, 18:23 |
|
AD, ты уже в который раз спускаешся до подробностей прикладного кода, складывается такое впечатление, что ты хочешь чтобы за тебя программу написали. |
BRE |
Дата 30.11.2009, 18:19 |
|
Или делать такой изврат:
void ContinueRotation::run() { connect(imitTsl, SIGNAL(continue_stop()), SLOT(exit())); connect(this, SIGNAL(working_light()), SLOT(workSpotlight()));
QTimer timerReading; connect(&timerReading, SIGNAL(timeout()), this, SLOT(reading())); timerReading.start(1000);
QEventLoop loop;
for(int timer_count=0; QTime::currentTime()<=finished_time;) { loop.processEvent();
if(_finished) break; timerTicks(); if(timer_count == 60) timer_count = 0; if(!timer_count) emit working_light(); ++timer_count; }
emit work_ending(); _is_time_read = false; }
Но я бы рекомендовал решить или согналы и exec, или свой цикл без сигналов.
|
AD |
Дата 30.11.2009, 18:18 |
|
Мда... Грустно, что нельзя это сделать. Задачка в следующем, которую никак не могу решить: В этом потоке я отправляю на COM-порт команды, которые принимает прожектор. Ну команды расшифровываются так: повернуть на столько-то вверх, на столько-то вправо, на столько-то вниз, на столько-то влево. Одновременно мне нужно принимать от прожектора команды и анализировать. Ну что оно уже повернул на столько-то.
В своем цикле у меня делается следующее:
for(int timer_count=0; QTime::currentTime()<=finished_time;) { if(_finished) break; timerTicks(); if(timer_count == 60) timer_count = 0; if(!timer_count) emit working_light(); ++timer_count; }
Имеется счетчик времени. При определенном значении этого счетчика (раз в минуту) запускается функция выдачи команд, которая и занимается отправкой команд:
/// Слот работы прожектора - вращения в обеих плоскостях void ContinueRotation::workSpotlight() { timerTicks(); geted_angle_elev = -1, geted_azimuth = -1;
/// Перемещение вниз и вправо до упора _angle_elevation = -110 * 10, _azimuth = 170 * 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(); _is_time_read = true; /// ВОТ ЗДЕСЬ МНЕ И НЕОБХОДИМО ПРОВЕРИТЬ НА СКОЛЬКО ОН УСПЕЛ ПОВЕРНУТЬСЯ. timerTicks();
/// Перемещение вверх и влево до упора _angle_elevation = 10 * 10; _azimuth = -170 * 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(); _is_time_read = true; /// ВОТ ЗДЕСЬ МНЕ И НЕОБХОДИМО ПРОВЕРИТЬ НА СКОЛЬКО ОН УСПЕЛ ПОВЕРНУТЬСЯ. 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::readAzimuth(int& geted_azimuth, double limit) { if(!imitTsl) return; QTime begining_time(QTime::currentTime()); 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); int secs = begining_time.secsTo(QTime::currentTime()); if(secs > 45) break; msleep(10); } }
/// Получение угла места void ContinueRotation::readAngleElevation(int& geted_angle_elev, double limit) { if(!imitTsl) return; QTime begining_time(QTime::currentTime()); 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); int secs = begining_time.secsTo(QTime::currentTime()); if(secs > 45) break; msleep(10); } }
/// Слот чтения из COM-порта void ContinueRotation::reading() { if(!_is_time_read) return;
readAngleElevation(geted_angle_elev, (double)_angle_elevation / 10.); readAzimuth(geted_azimuth, (double)_azimuth / 10.); _is_time_read = false; }
Если у кого-то возникнут идеи, как это сделать, буду благодарен. Пока никаких других идей не возникает.... |
BRE |
Дата 30.11.2009, 18:09 |
|
Цитата(AD @ 30.11.2009, 18:07) Ну... я уже ведь сказал, что запускается.... А я уже ответ написал. Смотри предыдущий ответ.
Цитата(AD @ 30.11.2009, 18:07) qDebug() выдает ошибку: Цитата error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'QDebug' (or there is no acceptable conversion) #include <QDebug> |
AD |
Дата 30.11.2009, 18:07 |
|
Ну... я уже ведь сказал, что запускается.... Проблема уже немного в другом: подружить мой цикл и вызов этого таймера... А вот как это сделать? qDebug() выдает ошибку:
Цитата error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'QDebug' (or there is no acceptable conversion)
|
Просмотр темы полностью (откроется в новом окне) |
|