~ubuntu-branches/ubuntu/raring/kstars/raring

« back to all changes in this revision

Viewing changes to kstars/ekos/guide/guider.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell, Jonathan Riddell, Harald Sitter
  • Date: 2012-11-19 16:07:49 UTC
  • mfrom: (1.1.16)
  • Revision ID: package-import@ubuntu.com-20121119160749-v7vdmo0iswx66dn8
Tags: 4:4.9.80-0ubuntu1
[ Jonathan Riddell ]
* New upstream beta release

[ Harald Sitter ]
* Build dep on wcslib-dev (new dep)
* Build dep on libindi-dev >= 0.9.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  Ekos guide tool
 
2
    Copyright (C) 2012 Andrew Stepanenko
 
3
 
 
4
    Modified by Jasem Mutlaq <mutlaqja@ikarustech.com> for KStars.
 
5
 
 
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.
 
10
 */
 
11
 
 
12
#include <math.h>
 
13
#include <stdlib.h>
 
14
#include <assert.h>
 
15
 
 
16
#include <KMessageBox>
 
17
 
 
18
#include "guider.h"
 
19
#include "scroll_graph.h"
 
20
#include "gmath.h"
 
21
 
 
22
#include "fitsviewer/fitsview.h"
 
23
 
 
24
#define DRIFT_GRAPH_WIDTH       300
 
25
#define DRIFT_GRAPH_HEIGHT      300
 
26
 
 
27
rguider::rguider(Ekos::Guide *parent)
 
28
    : QWidget(parent)
 
29
{
 
30
 int i;
 
31
 
 
32
        ui.setupUi(this);
 
33
 
 
34
    pmain_wnd = parent;
 
35
 
 
36
    pimage = NULL;
 
37
 
 
38
    lost_star_try=0;
 
39
 
 
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 ) );
 
43
 
 
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 ) );
 
47
 
 
48
        ui.spinBox_AccFramesRA->setMaximum( MAX_ACCUM_CNT );
 
49
        ui.spinBox_AccFramesDEC->setMaximum( MAX_ACCUM_CNT );
 
50
 
 
51
        // connect ui
 
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()) );
 
71
 
 
72
    connect(ui.captureB, SIGNAL(clicked()), pmain_wnd, SLOT(capture()));
 
73
 
 
74
        connect( ui.pushButton_StartStop, SIGNAL(clicked()), this, SLOT(onStartStopButtonClick()) );
 
75
 
 
76
        pmath = NULL;
 
77
 
 
78
        // init drift widget
 
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 );
 
83
 
 
84
        drift_graph = new cscroll_graph( this, DRIFT_GRAPH_WIDTH, DRIFT_GRAPH_HEIGHT );
 
85
        drift_graph->set_visible_ranges( DRIFT_GRAPH_WIDTH, 60 );
 
86
 
 
87
    pDriftOut->set_source( drift_graph->get_buffer(), NULL );
 
88
        drift_graph->on_paint();
 
89
 
 
90
        ui.frame_Graph->resize( DRIFT_GRAPH_WIDTH + 2*ui.frame_Graph->frameWidth(), DRIFT_GRAPH_HEIGHT + 2*ui.frame_Graph->frameWidth() );
 
91
 
 
92
        // not UI vars
 
93
        is_started = false;
 
94
    is_ready   = false;
 
95
        half_refresh_rate = false;
 
96
 
 
97
    //fill_interface();
 
98
 
 
99
}
 
100
 
 
101
rguider::~rguider()
 
102
{
 
103
    delete pDriftOut;
 
104
        delete drift_graph;
 
105
}
 
106
 
 
107
 
 
108
void rguider::set_half_refresh_rate( bool is_half )
 
109
{
 
110
        half_refresh_rate = is_half;
 
111
}
 
112
 
 
113
 
 
114
bool rguider::is_guiding( void ) const
 
115
{
 
116
        return is_started;
 
117
}
 
118
 
 
119
 
 
120
void rguider::set_math( cgmath *math )
 
121
{
 
122
        assert( math );
 
123
        pmath = math;
 
124
}
 
125
 
 
126
 
 
127
void rguider::fill_interface( void )
 
128
{
 
129
 const cproc_in_params *in_params;
 
130
 const cproc_out_params *out_params;
 
131
 info_params_t  info_params;
 
132
 QString str;
 
133
 int rx, ry;
 
134
 
 
135
 
 
136
        assert( pmath );
 
137
 
 
138
        info_params = pmath->get_info_params();
 
139
        in_params   = pmath->get_in_params();
 
140
        out_params  = pmath->get_out_params();
 
141
 
 
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() );
 
145
 
 
146
        ui.comboBox_SquareSize->setCurrentIndex( pmath->get_square_index() );
 
147
        ui.comboBox_ThresholdAlg->setCurrentIndex( pmath->get_square_algorithm_index() );
 
148
 
 
149
 
 
150
    ui.l_RecommendedGain->setText( i18n("P: %1", QString().setNum(cgmath::precalc_proportional_gain(in_params->guiding_rate), 'f', 2 )) );
 
151
 
 
152
 
 
153
        ui.spinBox_GuideRate->setValue( in_params->guiding_rate );
 
154
 
 
155
        // info params...
 
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 );
 
161
 
 
162
    ui.checkBox_DirRA->setChecked( in_params->enabled[GUIDE_RA] );
 
163
    ui.checkBox_DirDEC->setChecked( in_params->enabled[GUIDE_DEC] );
 
164
 
 
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] );
 
167
 
 
168
    ui.spinBox_PropGainRA->setValue( in_params->proportional_gain[GUIDE_RA] );
 
169
    ui.spinBox_PropGainDEC->setValue( in_params->proportional_gain[GUIDE_DEC] );
 
170
 
 
171
    ui.spinBox_IntGainRA->setValue( in_params->integral_gain[GUIDE_RA] );
 
172
    ui.spinBox_IntGainDEC->setValue( in_params->integral_gain[GUIDE_DEC] );
 
173
 
 
174
    ui.spinBox_DerGainRA->setValue( in_params->derivative_gain[GUIDE_RA] );
 
175
    ui.spinBox_DerGainDEC->setValue( in_params->derivative_gain[GUIDE_DEC] );
 
176
 
 
177
    ui.spinBox_MaxPulseRA->setValue( in_params->max_pulse_length[GUIDE_RA] );
 
178
    ui.spinBox_MaxPulseDEC->setValue( in_params->max_pulse_length[GUIDE_DEC] );
 
179
 
 
180
    ui.spinBox_MinPulseRA->setValue( in_params->min_pulse_length[GUIDE_RA] );
 
181
    ui.spinBox_MinPulseDEC->setValue( in_params->min_pulse_length[GUIDE_DEC] );
 
182
 
 
183
 
 
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) );
 
186
 
 
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]) );
 
189
 
 
190
    ui.l_ErrRA->setText( QString().setNum(out_params->sigma[GUIDE_RA]) );
 
191
    ui.l_ErrDEC->setText( QString().setNum(out_params->sigma[GUIDE_DEC]) );
 
192
 
 
193
}
 
194
 
 
195
 
 
196
void rguider::onXscaleChanged( int i )
 
197
{
 
198
 int rx, ry;
 
199
 
 
200
        drift_graph->get_visible_ranges( &rx, &ry );
 
201
        drift_graph->set_visible_ranges( i*drift_graph->get_grid_N(), ry );
 
202
 
 
203
        // refresh if not started
 
204
        if( !is_started )
 
205
        {
 
206
                drift_graph->on_paint();
 
207
 //             pDriftOut->update();
 
208
        }
 
209
 
 
210
}
 
211
 
 
212
 
 
213
void rguider::onYscaleChanged( int i )
 
214
{
 
215
 int rx, ry;
 
216
 
 
217
        drift_graph->get_visible_ranges( &rx, &ry );
 
218
        drift_graph->set_visible_ranges( rx, i*drift_graph->get_grid_N() );
 
219
 
 
220
        // refresh if not started
 
221
        if( !is_started )
 
222
        {
 
223
                drift_graph->on_paint();
 
224
//              pDriftOut->update();
 
225
        }
 
226
}
 
227
 
 
228
 
 
229
void rguider::onSquareSizeChanged( int index )
 
230
{
 
231
        if( pmath )
 
232
                pmath->resize_square( index );
 
233
}
 
234
 
 
235
 
 
236
void rguider::onThresholdChanged( int index )
 
237
{
 
238
        if( pmath )
 
239
                pmath->set_square_algorithm( index );
 
240
}
 
241
 
 
242
 
 
243
 
 
244
// params changing stuff
 
245
void rguider::onInfoRateChanged( double val )
 
246
{
 
247
 cproc_in_params *in_params;
 
248
 
 
249
 
 
250
        if( !pmath )
 
251
                return;
 
252
 
 
253
        in_params = pmath->get_in_params();
 
254
 
 
255
        in_params->guiding_rate = val;
 
256
 
 
257
    ui.l_RecommendedGain->setText( i18n("P: %1", QString().setNum(pmath->precalc_proportional_gain(in_params->guiding_rate), 'f', 2 )) );
 
258
}
 
259
 
 
260
 
 
261
void rguider::onEnableDirRA( int state )
 
262
{
 
263
 cproc_in_params *in_params;
 
264
 
 
265
        if( !pmath )
 
266
                return;
 
267
 
 
268
        in_params = pmath->get_in_params();
 
269
    in_params->enabled[GUIDE_RA] = (state == Qt::Checked);
 
270
}
 
271
 
 
272
 
 
273
void rguider::onEnableDirDEC( int state )
 
274
{
 
275
 cproc_in_params *in_params;
 
276
 
 
277
        if( !pmath )
 
278
                return;
 
279
 
 
280
        in_params = pmath->get_in_params();
 
281
    in_params->enabled[GUIDE_DEC] = (state == Qt::Checked);
 
282
}
 
283
 
 
284
 
 
285
void rguider::onInputParamChanged()
 
286
{
 
287
 QObject *obj;
 
288
 QSpinBox *pSB;
 
289
 QDoubleSpinBox *pDSB;
 
290
 cproc_in_params *in_params;
 
291
 
 
292
 
 
293
        if( !pmath )
 
294
                return;
 
295
 
 
296
        obj = sender();
 
297
 
 
298
        in_params = pmath->get_in_params();
 
299
 
 
300
        if( (pSB = dynamic_cast<QSpinBox *>(obj)) )
 
301
        {
 
302
                if( pSB == ui.spinBox_AccFramesRA )
 
303
            in_params->accum_frame_cnt[GUIDE_RA] = pSB->value();
 
304
                else
 
305
                if( pSB == ui.spinBox_AccFramesDEC )
 
306
            in_params->accum_frame_cnt[GUIDE_DEC] = pSB->value();
 
307
                else
 
308
                if( pSB == ui.spinBox_MaxPulseRA )
 
309
            in_params->max_pulse_length[GUIDE_RA] = pSB->value();
 
310
                else
 
311
                if( pSB == ui.spinBox_MaxPulseDEC )
 
312
            in_params->max_pulse_length[GUIDE_DEC] = pSB->value();
 
313
                else
 
314
                if( pSB == ui.spinBox_MinPulseRA )
 
315
            in_params->min_pulse_length[GUIDE_RA] = pSB->value();
 
316
                else
 
317
                if( pSB == ui.spinBox_MinPulseDEC )
 
318
            in_params->min_pulse_length[GUIDE_DEC] = pSB->value();
 
319
        }
 
320
        else
 
321
        if( (pDSB = dynamic_cast<QDoubleSpinBox *>(obj)) )
 
322
        {
 
323
                if( pDSB == ui.spinBox_PropGainRA )
 
324
            in_params->proportional_gain[GUIDE_RA] = pDSB->value();
 
325
                else
 
326
                if( pDSB == ui.spinBox_PropGainDEC )
 
327
            in_params->proportional_gain[GUIDE_DEC] = pDSB->value();
 
328
                else
 
329
                if( pDSB == ui.spinBox_IntGainRA )
 
330
            in_params->integral_gain[GUIDE_RA] = pDSB->value();
 
331
                else
 
332
                if( pDSB == ui.spinBox_IntGainDEC )
 
333
            in_params->integral_gain[GUIDE_DEC] = pDSB->value();
 
334
                else
 
335
                if( pDSB == ui.spinBox_DerGainRA )
 
336
            in_params->derivative_gain[GUIDE_RA] = pDSB->value();
 
337
                else
 
338
                if( pDSB == ui.spinBox_DerGainDEC )
 
339
            in_params->derivative_gain[GUIDE_DEC] = pDSB->value();
 
340
        }
 
341
 
 
342
}
 
343
 
 
344
 
 
345
 
 
346
 
 
347
 
 
348
// processing stuff
 
349
void rguider::onStartStopButtonClick()
 
350
{
 
351
        assert( pmath );
 
352
 
 
353
        // start
 
354
        if( !is_started )
 
355
        {
 
356
        if (pimage)
 
357
            disconnect(pimage, SIGNAL(guideStarSelected(int,int)), 0, 0);
 
358
 
 
359
                drift_graph->reset_data();
 
360
        ui.pushButton_StartStop->setText( i18n("Stop") );
 
361
        pmain_wnd->appendLogText(i18n("Autoguiding started."));
 
362
                pmath->start();
 
363
        lost_star_try=0;
 
364
                is_started = true;
 
365
        pmain_wnd->capture();
 
366
        }
 
367
        // stop
 
368
        else
 
369
        {
 
370
        if (pimage)
 
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."));
 
374
                pmath->stop();
 
375
                // stop pulses immediately
 
376
//              if( !DBG_VERBOSITY )
 
377
//                      pmain_wnd->m_driver->reset();
 
378
 
 
379
 
 
380
 
 
381
                is_started = false;
 
382
        }
 
383
}
 
384
 
 
385
 
 
386
void rguider::guide( void )
 
387
{
 
388
 const cproc_out_params *out;
 
389
 QString str;
 
390
 uint32_t tick = 0;
 
391
 double drift_x = 0, drift_y = 0;
 
392
 
 
393
 
 
394
         assert( pmath );
 
395
 
 
396
         // calc math. it tracks square
 
397
         pmath->do_processing();
 
398
 
 
399
         if( !isVisible() || !is_started )
 
400
                 return;
 
401
 
 
402
     if (pmath->is_lost_star() && ++lost_star_try > 2)
 
403
     {
 
404
         onStartStopButtonClick();
 
405
         KMessageBox::error(NULL, i18n("Lost track of the guide star. Try increasing the square size and check the mount."));
 
406
         return;
 
407
     }
 
408
     else
 
409
         lost_star_try = 0;
 
410
 
 
411
         // do pulse
 
412
         out = pmath->get_out_params();
 
413
 
 
414
 
 
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;
 
418
 
 
419
 
 
420
         pmath->get_star_drift( &drift_x, &drift_y );
 
421
 
 
422
         drift_graph->add_point( drift_x, drift_y );
 
423
 
 
424
         tick = pmath->get_ticks();
 
425
 
 
426
 
 
427
         if( tick & 1 )
 
428
         {
 
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) );
 
432
 
 
433
         ui.l_PulseRA->setText(str.setNum(out->pulse_length[GUIDE_RA]) );
 
434
         ui.l_PulseDEC->setText(str.setNum(out->pulse_length[GUIDE_DEC]) );
 
435
 
 
436
         ui.l_ErrRA->setText( str.setNum(out->sigma[GUIDE_RA]) );
 
437
         ui.l_ErrDEC->setText( str.setNum(out->sigma[GUIDE_DEC]) );
 
438
         }
 
439
 
 
440
         // skip half frames
 
441
         if( half_refresh_rate && (tick & 1) )
 
442
                return;
 
443
 
 
444
     drift_graph->on_paint();
 
445
     pDriftOut->update();
 
446
 
 
447
}
 
448
 
 
449
void rguider::set_image(FITSView *image)
 
450
{
 
451
    pimage = image;
 
452
 
 
453
    if (is_ready && pimage && is_started == false)
 
454
        connect(pimage, SIGNAL(guideStarSelected(int,int)), this, SLOT(guideStarSelected(int, int)));
 
455
}
 
456
 
 
457
void rguider::guideStarSelected(int x, int y)
 
458
{
 
459
    int square_size = guide_squares[pmath->get_square_index()].size;
 
460
 
 
461
    pmath->set_reticle_params(x, y, pmain_wnd->getReticleAngle());
 
462
    pmath->move_square(x-square_size/2, y-square_size/2);
 
463
 
 
464
    disconnect(pimage, SIGNAL(guideStarSelected(int,int)), this, SLOT(guideStarSelected(int, int)));
 
465
 
 
466
}
 
467
 
 
468
 
 
469