2
Copyright (C) 2012 Andrew Stepanenko
4
Modified by Jasem Mutlaq <mutlaqja@ikarustech.com> for KStars.
6
This application is free software; you can redistribute it and/or
7
modify it under the terms of the GNU General Public
8
License as published by the Free Software Foundation; either
9
version 2 of the License, or (at your option) any later version.
16
#include <KMessageBox>
19
#include "scroll_graph.h"
22
#include "fitsviewer/fitsview.h"
24
#define DRIFT_GRAPH_WIDTH 300
25
#define DRIFT_GRAPH_HEIGHT 300
27
rguider::rguider(Ekos::Guide *parent)
40
ui.comboBox_SquareSize->clear();
41
for( i = 0;guide_squares[i].size != -1;i++ )
42
ui.comboBox_SquareSize->addItem( QString().setNum( guide_squares[i].size ) );
44
ui.comboBox_ThresholdAlg->clear();
45
for( i = 0;guide_square_alg[i].idx != -1;i++ )
46
ui.comboBox_ThresholdAlg->addItem( QString( guide_square_alg[i].name ) );
48
ui.spinBox_AccFramesRA->setMaximum( MAX_ACCUM_CNT );
49
ui.spinBox_AccFramesDEC->setMaximum( MAX_ACCUM_CNT );
52
connect( ui.spinBox_XScale, SIGNAL(valueChanged(int)), this, SLOT(onXscaleChanged(int)) );
53
connect( ui.spinBox_YScale, SIGNAL(valueChanged(int)), this, SLOT(onYscaleChanged(int)) );
54
connect( ui.comboBox_SquareSize, SIGNAL(activated(int)), this, SLOT(onSquareSizeChanged(int)) );
55
connect( ui.comboBox_ThresholdAlg, SIGNAL(activated(int)), this, SLOT(onThresholdChanged(int)) );
56
connect( ui.spinBox_GuideRate, SIGNAL(valueChanged(double)), this, SLOT(onInfoRateChanged(double)) );
57
connect( ui.checkBox_DirRA, SIGNAL(stateChanged(int)), this, SLOT(onEnableDirRA(int)) );
58
connect( ui.checkBox_DirDEC, SIGNAL(stateChanged(int)), this, SLOT(onEnableDirDEC(int)) );
59
connect( ui.spinBox_AccFramesRA, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
60
connect( ui.spinBox_AccFramesDEC, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
61
connect( ui.spinBox_PropGainRA, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
62
connect( ui.spinBox_PropGainDEC, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
63
connect( ui.spinBox_IntGainRA, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
64
connect( ui.spinBox_IntGainDEC, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
65
connect( ui.spinBox_DerGainRA, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
66
connect( ui.spinBox_DerGainDEC, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
67
connect( ui.spinBox_MaxPulseRA, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
68
connect( ui.spinBox_MaxPulseDEC, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
69
connect( ui.spinBox_MinPulseRA, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
70
connect( ui.spinBox_MinPulseDEC, SIGNAL(editingFinished()), this, SLOT(onInputParamChanged()) );
72
connect(ui.captureB, SIGNAL(clicked()), pmain_wnd, SLOT(capture()));
74
connect( ui.pushButton_StartStop, SIGNAL(clicked()), this, SLOT(onStartStopButtonClick()) );
79
pDriftOut = new custom_drawer( ui.frame_Graph );
80
pDriftOut->move( ui.frame_Graph->frameWidth(), ui.frame_Graph->frameWidth() );
81
pDriftOut->setAttribute( Qt::WA_NoSystemBackground, true );
82
ui.frame_Graph->setAttribute( Qt::WA_NoSystemBackground, true );
84
drift_graph = new cscroll_graph( this, DRIFT_GRAPH_WIDTH, DRIFT_GRAPH_HEIGHT );
85
drift_graph->set_visible_ranges( DRIFT_GRAPH_WIDTH, 60 );
87
pDriftOut->set_source( drift_graph->get_buffer(), NULL );
88
drift_graph->on_paint();
90
ui.frame_Graph->resize( DRIFT_GRAPH_WIDTH + 2*ui.frame_Graph->frameWidth(), DRIFT_GRAPH_HEIGHT + 2*ui.frame_Graph->frameWidth() );
95
half_refresh_rate = false;
108
void rguider::set_half_refresh_rate( bool is_half )
110
half_refresh_rate = is_half;
114
bool rguider::is_guiding( void ) const
120
void rguider::set_math( cgmath *math )
127
void rguider::fill_interface( void )
129
const cproc_in_params *in_params;
130
const cproc_out_params *out_params;
131
info_params_t info_params;
138
info_params = pmath->get_info_params();
139
in_params = pmath->get_in_params();
140
out_params = pmath->get_out_params();
142
drift_graph->get_visible_ranges( &rx, &ry );
143
ui.spinBox_XScale->setValue( rx / drift_graph->get_grid_N() );
144
ui.spinBox_YScale->setValue( ry / drift_graph->get_grid_N() );
146
ui.comboBox_SquareSize->setCurrentIndex( pmath->get_square_index() );
147
ui.comboBox_ThresholdAlg->setCurrentIndex( pmath->get_square_algorithm_index() );
150
ui.l_RecommendedGain->setText( i18n("P: %1", QString().setNum(cgmath::precalc_proportional_gain(in_params->guiding_rate), 'f', 2 )) );
153
ui.spinBox_GuideRate->setValue( in_params->guiding_rate );
156
ui.l_Focal->setText( str.setNum( (int)info_params.focal) );
157
ui.l_Aperture->setText( str.setNum( (int)info_params.aperture) );
158
ui.l_FbyD->setText( QString().setNum( info_params.focal_ratio, 'f', 1) );
159
str = QString().setNum(info_params.fov_wd, 'f', 1) + "x" + QString().setNum(info_params.fov_ht, 'f', 1);
160
ui.l_FOV->setText( str );
162
ui.checkBox_DirRA->setChecked( in_params->enabled[GUIDE_RA] );
163
ui.checkBox_DirDEC->setChecked( in_params->enabled[GUIDE_DEC] );
165
ui.spinBox_AccFramesRA->setValue( (int)in_params->accum_frame_cnt[GUIDE_RA] );
166
ui.spinBox_AccFramesDEC->setValue( (int)in_params->accum_frame_cnt[GUIDE_DEC] );
168
ui.spinBox_PropGainRA->setValue( in_params->proportional_gain[GUIDE_RA] );
169
ui.spinBox_PropGainDEC->setValue( in_params->proportional_gain[GUIDE_DEC] );
171
ui.spinBox_IntGainRA->setValue( in_params->integral_gain[GUIDE_RA] );
172
ui.spinBox_IntGainDEC->setValue( in_params->integral_gain[GUIDE_DEC] );
174
ui.spinBox_DerGainRA->setValue( in_params->derivative_gain[GUIDE_RA] );
175
ui.spinBox_DerGainDEC->setValue( in_params->derivative_gain[GUIDE_DEC] );
177
ui.spinBox_MaxPulseRA->setValue( in_params->max_pulse_length[GUIDE_RA] );
178
ui.spinBox_MaxPulseDEC->setValue( in_params->max_pulse_length[GUIDE_DEC] );
180
ui.spinBox_MinPulseRA->setValue( in_params->min_pulse_length[GUIDE_RA] );
181
ui.spinBox_MinPulseDEC->setValue( in_params->min_pulse_length[GUIDE_DEC] );
184
ui.l_DeltaRA->setText(QString().setNum(out_params->delta[GUIDE_RA], 'f', 2) );
185
ui.l_DeltaDEC->setText(QString().setNum(out_params->delta[GUIDE_DEC], 'f', 2) );
187
ui.l_PulseRA->setText(QString().setNum(out_params->pulse_length[GUIDE_RA]) );
188
ui.l_PulseDEC->setText(QString().setNum(out_params->pulse_length[GUIDE_DEC]) );
190
ui.l_ErrRA->setText( QString().setNum(out_params->sigma[GUIDE_RA]) );
191
ui.l_ErrDEC->setText( QString().setNum(out_params->sigma[GUIDE_DEC]) );
196
void rguider::onXscaleChanged( int i )
200
drift_graph->get_visible_ranges( &rx, &ry );
201
drift_graph->set_visible_ranges( i*drift_graph->get_grid_N(), ry );
203
// refresh if not started
206
drift_graph->on_paint();
207
// pDriftOut->update();
213
void rguider::onYscaleChanged( int i )
217
drift_graph->get_visible_ranges( &rx, &ry );
218
drift_graph->set_visible_ranges( rx, i*drift_graph->get_grid_N() );
220
// refresh if not started
223
drift_graph->on_paint();
224
// pDriftOut->update();
229
void rguider::onSquareSizeChanged( int index )
232
pmath->resize_square( index );
236
void rguider::onThresholdChanged( int index )
239
pmath->set_square_algorithm( index );
244
// params changing stuff
245
void rguider::onInfoRateChanged( double val )
247
cproc_in_params *in_params;
253
in_params = pmath->get_in_params();
255
in_params->guiding_rate = val;
257
ui.l_RecommendedGain->setText( i18n("P: %1", QString().setNum(pmath->precalc_proportional_gain(in_params->guiding_rate), 'f', 2 )) );
261
void rguider::onEnableDirRA( int state )
263
cproc_in_params *in_params;
268
in_params = pmath->get_in_params();
269
in_params->enabled[GUIDE_RA] = (state == Qt::Checked);
273
void rguider::onEnableDirDEC( int state )
275
cproc_in_params *in_params;
280
in_params = pmath->get_in_params();
281
in_params->enabled[GUIDE_DEC] = (state == Qt::Checked);
285
void rguider::onInputParamChanged()
289
QDoubleSpinBox *pDSB;
290
cproc_in_params *in_params;
298
in_params = pmath->get_in_params();
300
if( (pSB = dynamic_cast<QSpinBox *>(obj)) )
302
if( pSB == ui.spinBox_AccFramesRA )
303
in_params->accum_frame_cnt[GUIDE_RA] = pSB->value();
305
if( pSB == ui.spinBox_AccFramesDEC )
306
in_params->accum_frame_cnt[GUIDE_DEC] = pSB->value();
308
if( pSB == ui.spinBox_MaxPulseRA )
309
in_params->max_pulse_length[GUIDE_RA] = pSB->value();
311
if( pSB == ui.spinBox_MaxPulseDEC )
312
in_params->max_pulse_length[GUIDE_DEC] = pSB->value();
314
if( pSB == ui.spinBox_MinPulseRA )
315
in_params->min_pulse_length[GUIDE_RA] = pSB->value();
317
if( pSB == ui.spinBox_MinPulseDEC )
318
in_params->min_pulse_length[GUIDE_DEC] = pSB->value();
321
if( (pDSB = dynamic_cast<QDoubleSpinBox *>(obj)) )
323
if( pDSB == ui.spinBox_PropGainRA )
324
in_params->proportional_gain[GUIDE_RA] = pDSB->value();
326
if( pDSB == ui.spinBox_PropGainDEC )
327
in_params->proportional_gain[GUIDE_DEC] = pDSB->value();
329
if( pDSB == ui.spinBox_IntGainRA )
330
in_params->integral_gain[GUIDE_RA] = pDSB->value();
332
if( pDSB == ui.spinBox_IntGainDEC )
333
in_params->integral_gain[GUIDE_DEC] = pDSB->value();
335
if( pDSB == ui.spinBox_DerGainRA )
336
in_params->derivative_gain[GUIDE_RA] = pDSB->value();
338
if( pDSB == ui.spinBox_DerGainDEC )
339
in_params->derivative_gain[GUIDE_DEC] = pDSB->value();
349
void rguider::onStartStopButtonClick()
357
disconnect(pimage, SIGNAL(guideStarSelected(int,int)), 0, 0);
359
drift_graph->reset_data();
360
ui.pushButton_StartStop->setText( i18n("Stop") );
361
pmain_wnd->appendLogText(i18n("Autoguiding started."));
365
pmain_wnd->capture();
371
connect(pimage, SIGNAL(guideStarSelected(int,int)), this, SLOT(guideStarSelected(int,int)));
372
ui.pushButton_StartStop->setText( i18n("Start") );
373
pmain_wnd->appendLogText(i18n("Autoguiding stopped."));
375
// stop pulses immediately
376
// if( !DBG_VERBOSITY )
377
// pmain_wnd->m_driver->reset();
386
void rguider::guide( void )
388
const cproc_out_params *out;
391
double drift_x = 0, drift_y = 0;
396
// calc math. it tracks square
397
pmath->do_processing();
399
if( !isVisible() || !is_started )
402
if (pmath->is_lost_star() && ++lost_star_try > 2)
404
onStartStopButtonClick();
405
KMessageBox::error(NULL, i18n("Lost track of the guide star. Try increasing the square size and check the mount."));
412
out = pmath->get_out_params();
415
//qDebug() << "Guide is sending pulse command now ... " << endl;
416
pmain_wnd->do_pulse( out->pulse_dir[GUIDE_RA], out->pulse_length[GUIDE_RA], out->pulse_dir[GUIDE_DEC], out->pulse_length[GUIDE_DEC] );
417
//qDebug() << "#######################################" << endl;
420
pmath->get_star_drift( &drift_x, &drift_y );
422
drift_graph->add_point( drift_x, drift_y );
424
tick = pmath->get_ticks();
429
// draw some params in window
430
ui.l_DeltaRA->setText(str.setNum(out->delta[GUIDE_RA], 'f', 2) );
431
ui.l_DeltaDEC->setText(str.setNum(out->delta[GUIDE_DEC], 'f', 2) );
433
ui.l_PulseRA->setText(str.setNum(out->pulse_length[GUIDE_RA]) );
434
ui.l_PulseDEC->setText(str.setNum(out->pulse_length[GUIDE_DEC]) );
436
ui.l_ErrRA->setText( str.setNum(out->sigma[GUIDE_RA]) );
437
ui.l_ErrDEC->setText( str.setNum(out->sigma[GUIDE_DEC]) );
441
if( half_refresh_rate && (tick & 1) )
444
drift_graph->on_paint();
449
void rguider::set_image(FITSView *image)
453
if (is_ready && pimage && is_started == false)
454
connect(pimage, SIGNAL(guideStarSelected(int,int)), this, SLOT(guideStarSelected(int, int)));
457
void rguider::guideStarSelected(int x, int y)
459
int square_size = guide_squares[pmath->get_square_index()].size;
461
pmath->set_reticle_params(x, y, pmain_wnd->getReticleAngle());
462
pmath->move_square(x-square_size/2, y-square_size/2);
464
disconnect(pimage, SIGNAL(guideStarSelected(int,int)), this, SLOT(guideStarSelected(int, int)));