/// Класс потока - вращение вокруг осей заданное количество времени - длительное вращение
class ContinueRotation: public QThread
{
Q_OBJECT
private:
QTime _time; ///< счетчик времени вращения прожектора
QTime starting_time, finished_time; ///< время начала и окончания отсчета
private:
void readAzimuth(int& geted_azimuth, double limit);
void readAngleElevation(int& geted_angle_elev, double limit);
protected:
virtual void run();
signals:
void timeout(QTime);
public:
ContinueRotation(QObject *parent);
~ContinueRotation();
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);
};
/// Установка времен начала и окончания работы прожектора
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::run()
{
while(_time.hour() || _time.minute() || _time.second() || _time.msec())
{
int secs = QDateTime::currentDateTime().time().secsTo(finished_time);
QTime t; t = t.addSecs(secs);
_time = t;
emit timeout(_time);
}
}
/// Класс отображения параметров работы в автоматическом режиме продолжительное время
class ContinuousWork: public QWidget, public ContinuousWorkClass
{
Q_OBJECT
private:
ContinueRotation* _continue; ///< указатель на класс потока, выполняющий необходимое вращение
private slots:
void changeHour(int h);
void startControl();
void elapsedTime(QTime t) { editElapsedTime -> setTime(t); } ///< editElapsedTime - имеет тип QTimeEdit
public:
ContinuousWork(QWidget *parent = 0);
~ContinuousWork();
};
ContinuousWork::ContinuousWork(QWidget *parent): QWidget(parent)
_continue(new ContinueRotation(parent))
{
// anybody
connect(btnStartControl, SIGNAL(clicked()), this, SLOT(startControl()));
connect(_continue, SIGNAL(timeout(QTime)), SLOT(elapsedTime(QTime)));
}
/// Запуск работы прожектора
void ContinuousWork::startControl()
{
_continue -> setTime(spinHours -> value(), spinMinutes -> value());
_continue -> setStartingTime(QDateTime::currentDateTime().time());
_continue -> start();
}
void ContinueRotation::run()
{
while(_time.hour() || _time.minute() || _time.second() || _time.msec())
{
int secs = QDateTime::currentDateTime().time().secsTo(finished_time);
QTime t; t = t.addSecs(secs);
_time = t;
emit timeout(_time);
}
}
/// Запуск потока вращения в обеих плоскостях длительный промежуток времени
void ContinueRotation::run()
{
while(_time.hour() || _time.minute() || _time.second() || _time.msec())
{
int secs = QDateTime::currentDateTime().time().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();
int diff = _t - el_t;
_time = t;
if(diff >= 1000) emit timeout(_time);
}
}
/// Запуск потока вращения в обеих плоскостях длительный промежуток времени
void ContinueRotation::run()
{
while(_time.hour() || _time.minute() || _time.second() || _time.msec())
{
int secs = QDateTime::currentDateTime().time().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();
int diff = _t - el_t;
_time = t;
if(diff >= 1000) emit timeout(_time);
}
}
int secs = QTime::currentTime().secsTo(finished_time);
int secs = QTime::currentTime().secsTo(finished_time);
QTime finished_time(0,0,0);
int secs = QTime::currentTime().secsTo(finished_time);
qDebug() << secs;
void ContinueRotation::run()
{
const int pause = 1000 * 60;
QDateTime startDT = QDateTime::currentDateTime();
while(finish_datatime >= startDT) {
msleep(pause);
startDT = QDateTime::currentDateTime();
//emit - эмитируем сигнал с периодом "pause".
}
}
QTime p(0, 0, 25, 100);
int secs = QTime::currentTime().secsTo(p);
QTime t; t = t.addSecs(secs);
/// Класс потока - вращение вокруг осей заданное количество времени - длительное вращение
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();
}
/// Запуск потока вращения в обеих плоскостях длительный промежуток времени
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();
}
void ContinueRotation::run()
{
const int pause = 1000 * 60;
QDateTime startDT = QDateTime::currentDateTime();
while(finish_datatime >= startDT) {
msleep(pause);
startDT = QDateTime::currentDateTime();
//emit - эмитируем сигнал с периодом "pause".
}
}
/// В классе.
signals:
void _timeout(QTime);
void working_light();
/// Слот работы прожектора - вращения в обеих плоскостях
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();
int timer_count = 0;
connect(this, SIGNAL(working_light()), SLOT(workSpotlight()));
while(QTime::currentTime() <= finished_time)
{
timerTicks();
if(timer_count == 60) timer_count = 0;
if(!timer_count) emit working_light();
msleep(1000);
++timer_count;
}
if(QTime::currentTime() > finished_time && _working_spotlight.isActive())
_working_spotlight.stop();
}