Commit 40b5cc74 authored by Jasem Mutlaq's avatar Jasem Mutlaq
Browse files

More progress on guide operation. Now internal guiding basically works. Need...

More progress on guide operation. Now internal guiding basically works. Need to use QCustomPlot for plotting instead of legacy one
parent 8e306483
......@@ -75,7 +75,7 @@ Guide::Guide() : QWidget()
guideWidget->setLayout(vlayout);
connect(guideView, SIGNAL(trackingStarSelected(int,int)), this, SLOT(setTrackingStar(int,int)));
ccd_hor_pixel = ccd_ver_pixel = focal_length = aperture = -1;
ccdPixelSizeX = ccdPixelSizeY = mountAperture = mountFocalLength = pixScaleX = pixScaleY = -1;
guideDeviationRA = guideDeviationDEC = 0;
useGuideHead = false;
......@@ -110,7 +110,7 @@ Guide::Guide() : QWidget()
connect(darkFrameCheck, SIGNAL(toggled(bool)), this, SLOT(setDarkFrameEnabled(bool)));
// ST4 Selection
connect(ST4Combo, SIGNAL(currentIndexChanged(int)), this, SLOT(newST4(int)));
connect(ST4Combo, SIGNAL(currentIndexChanged(int)), this, SLOT(setST4(int)));
//connect(ST4Combo, SIGNAL(activated(QString)), this, SLOT(setDefaultST4(QString)));
//connect(ST4Combo, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::activated), this, [&](const QString & st4){Options::setDefaultST4Driver(st4);});
......@@ -166,6 +166,9 @@ Guide::Guide() : QWidget()
// Calibrate
connect(calibrateB, SIGNAL(clicked()), this, SLOT(calibrate()));
// Guide
connect(guideB, SIGNAL(clicked()), this, SLOT(guide()));
// Drift Graph
//driftGraph = new ScrollGraph( this, driftGraph_WIDTH, driftGraph_HEIGHT );
//driftGraphics->setSize(driftGraph_WIDTH, driftGraph_HEIGHT);
......@@ -232,6 +235,10 @@ Guide::Guide() : QWidget()
connect(guider, SIGNAL(newStatus(Ekos::GuideState)), this, SLOT(setStatus(Ekos::GuideState)));
connect(guider, SIGNAL(newStarPosition(QVector3D,bool)), this, SLOT(setStarPosition(QVector3D,bool)));
connect(guider, SIGNAL(newAxisDelta(double,double)), this, SLOT(setAxisDelta(double,double)));
connect(guider, SIGNAL(newAxisPulse(double,double)), this, SLOT(setAxisPulse(double,double)));
connect(guider, SIGNAL(newAxisSigma(double,double)), this, SLOT(setAxisSigma(double,double)));
// FIXME we emit this directly TODO
//connect(guider, SIGNAL(newProfilePixmap(QPixmap &)), this, SIGNAL(newProfilePixmap(QPixmap &)));
......@@ -399,15 +406,15 @@ void Guide::syncCCDInfo()
{
INumber *np = IUFindNumber(nvp, "CCD_PIXEL_SIZE_X");
if (np)
ccd_hor_pixel = np->value;
ccdPixelSizeX = np->value;
np = IUFindNumber(nvp, "CCD_PIXEL_SIZE_Y");
if (np)
ccd_ver_pixel = np->value;
ccdPixelSizeY = np->value;
np = IUFindNumber(nvp, "CCD_PIXEL_SIZE_Y");
if (np)
ccd_ver_pixel = np->value;
ccdPixelSizeY = np->value;
}
updateGuideParams();
......@@ -425,22 +432,22 @@ void Guide::syncTelescopeInfo()
INumber *np = IUFindNumber(nvp, "GUIDER_APERTURE");
if (np && np->value != 0)
aperture = np->value;
mountAperture = np->value;
else
{
np = IUFindNumber(nvp, "TELESCOPE_APERTURE");
if (np)
aperture = np->value;
mountAperture = np->value;
}
np = IUFindNumber(nvp, "GUIDER_FOCAL_LENGTH");
if (np && np->value != 0)
focal_length = np->value;
mountFocalLength = np->value;
else
{
np = IUFindNumber(nvp, "TELESCOPE_FOCAL_LENGTH");
if (np)
focal_length = np->value;
mountFocalLength = np->value;
}
}
......@@ -484,9 +491,9 @@ void Guide::updateGuideParams()
binningCombo->blockSignals(false);
}
if (ccd_hor_pixel != -1 && ccd_ver_pixel != -1 && focal_length != -1 && aperture != -1)
if (ccdPixelSizeX != -1 && ccdPixelSizeY != -1 && mountAperture != -1 && mountFocalLength != -1)
{
guider->setGuiderParams(ccd_hor_pixel, ccd_ver_pixel, aperture, focal_length);
guider->setGuiderParams(ccdPixelSizeX, ccdPixelSizeY, mountAperture, mountFocalLength);
//pmath->setGuiderParameters(ccd_hor_pixel, ccd_ver_pixel, aperture, focal_length);
//phd2->setCCDMountParams(ccd_hor_pixel, ccd_ver_pixel, focal_length);
......@@ -503,6 +510,19 @@ void Guide::updateGuideParams()
//guider->setInterface();
l_Focal->setText(QString::number(mountFocalLength, 'f', 1));
l_Aperture->setText(QString::number(mountAperture, 'f', 1));
l_FbyD->setText(QString::number(mountFocalLength/mountAperture, 'f', 1));
// Pixel scale in arcsec/pixel
pixScaleX = 206264.8062470963552 * ccdPixelSizeX / 1000.0 / mountFocalLength;
pixScaleY = 206264.8062470963552 * ccdPixelSizeY / 1000.0 / mountFocalLength;
// FOV in arcmin
double fov_w = (w*pixScaleX)/60.0;
double fov_h = (h*pixScaleY)/60.0;
l_FOV->setText(QString("%1x%2").arg(QString::number(fov_w, 'f', 1)).arg(QString::number(fov_h, 'f', 1)));
}
}
......@@ -538,7 +558,7 @@ bool Guide::setST4(QString device)
return false;
}
void Guide::newST4(int index)
void Guide::setST4(int index)
{
if (ST4List.empty() || index >= ST4List.count())
return;
......@@ -645,21 +665,13 @@ bool Guide::abort()
case GUIDE_CALIBRATING:
case GUIDE_CALIBRATION_STAR:
case GUIDE_CALIBRATION_CAPTURE:
case GUIDE_GUIDING:
guider->abort();
default:
break;
}
// Maybe set this above?
if (state >= GUIDE_CALIBRATING)
state = GUIDE_ABORTED;
else
state = GUIDE_IDLE;
emit newStatus(state);
return true;
}
......@@ -821,6 +833,10 @@ void Guide::setCaptureComplete()
guider->calibrate();
break;
case GUIDE_GUIDING:
guider->guide();
break;
default:
break;
......@@ -1040,60 +1056,6 @@ void Guide::stopRapidGuide()
}
void Guide::dither()
{
// FIXME
/*
if (Options::useEkosGuider())
{
if (isDithering() == false)
guider->dither();
}
else
{
if (isDithering() == false)
phd2->dither(guider->getDitherPixels());
}
*/
}
void Guide::updateGuideDriver(double delta_ra, double delta_dec)
{
// FIXME
/*
guideDeviationRA = delta_ra;
guideDeviationDEC = delta_dec;
// If using PHD2 or not guiding, no need to go further on
if (Options::usePHD2Guider() || isGuiding() == false)
return;
if (isDithering())
{
GuideDriver = ST4Driver;
return;
}
// Guide via AO only if guiding deviation is below AO limit
if (AODriver != NULL && (fabs(delta_ra) < guider->getAOLimit()) && (fabs(delta_dec) < guider->getAOLimit()))
{
if (AODriver != GuideDriver)
appendLogText(i18n("Using %1 to correct for guiding errors.", AODriver->getDeviceName()));
GuideDriver = AODriver;
return;
}
if (GuideDriver != ST4Driver)
appendLogText(i18n("Using %1 to correct for guiding errors.", ST4Driver->getDeviceName()));
GuideDriver = ST4Driver;
*/
}
bool Guide::calibrate()
{
saveSettings();
......@@ -1126,7 +1088,6 @@ bool Guide::guide()
if (rc)
{
appendLogText(i18n("Autoguiding started."));
driftGraphics->resetData();
}
......@@ -1291,6 +1252,11 @@ void Guide::setStatus(Ekos::GuideState newState)
setBusy(false);
break;
case GUIDE_GUIDING:
appendLogText(i18n("Autoguiding started."));
setBusy(true);
break;
default:
break;
}
......@@ -1737,6 +1703,29 @@ void Guide::setTrackingStar(int x, int y)
}
}
void Guide::setAxisDelta(double ra, double de)
{
driftGraphics->addPoint(ra, de);
driftGraphics->update();
l_DeltaRA->setText(QString::number(ra, 'f', 2));
l_DeltaDEC->setText(QString::number(de, 'f', 2));
emit newAxisDelta(ra,de);
}
void Guide::setAxisSigma(double ra, double de)
{
l_ErrRA->setText(QString::number(ra, 'f', 2));
l_ErrDEC->setText(QString::number(de, 'f', 2));
}
void Guide::setAxisPulse(double ra, double de)
{
l_PulseRA->setText(QString::number(static_cast<int>(ra)));
l_PulseDEC->setText(QString::number(static_cast<int>(de)));
}
}
......@@ -179,7 +179,7 @@ public:
void addCCD(ISD::GDInterface *newCCD);
void setTelescope(ISD::GDInterface *newTelescope);
void addST4(ISD::ST4 *newST4);
void addST4(ISD::ST4 *setST4);
void setAO(ISD::ST4 *newAO);
bool isDithering();
......@@ -188,12 +188,26 @@ public:
void syncTelescopeInfo();
void syncCCDInfo();
/**
* @brief clearLog As the name suggests
*/
void clearLog();
/**
* @brief setDECSwap Change ST4 declination pulse direction. +DEC pulses increase DEC if swap is OFF. When on +DEC pulses result in decreasing DEC.
* @param enable True to enable DEC swap. Off to disable it.
*/
void setDECSwap(bool enable);
/**
* @return Return curent log text of guide module
*/
QString getLogText() { return logText.join("\n"); }
/**
* @brief getStarPosition Return star center as selected by the user or auto-detected by KStars
* @return QVector3D of starCenter. The 3rd parameter is used to store current bin settings and in unrelated to the star position.
*/
QVector3D getStarPosition() { return starCenter; }
// Tracking Box
......@@ -242,18 +256,44 @@ public slots:
*/
Q_SCRIPTABLE bool selectAutoStar();
/**
* @brief checkCCD Check all CCD parameters and ensure all variables are updated to reflect the selected CCD
* @param ccdNum CCD index number in the CCD selection combo box
*/
void checkCCD(int ccdNum=-1);
/**
* @brief checkExposureValue This function is called by the INDI framework whenever there is a new exposure value. We use it to know if there is a problem with the exposure
* @param targetChip Chip for which the exposure is undergoing
* @param exposure numbers of seconds left in the exposure
* @param state State of the exposure property
*/
void checkExposureValue(ISD::CCDChip *targetChip, double exposure, IPState state);
/**
* @brief newFITS is called by the INDI framework whenever there is a new BLOB arriving
*/
void newFITS(IBLOB*);
void newST4(int index);
/**
* @brief setST4 Sets a new ST4 device from the combobox index
* @param index Index of selected ST4 in the combobox
*/
void setST4(int index);
/**
* @brief processRapidStarData is called by INDI framework when we receive new Rapid Guide data
* @param targetChip target Chip for which rapid guide is enabled
* @param dx Deviation in X
* @param dy Deviation in Y
* @param fit fitting score
*/
void processRapidStarData(ISD::CCDChip *targetChip, double dx, double dy, double fit);
void updateGuideDriver(double delta_ra, double delta_dec);
// Auto Calibration Guiding (Cablirate first then start guiding immediately)
void startAutoCalibrateGuiding();
void checkAutoCalibrateGuiding(Ekos::GuideState state);
void dither();
void setSuspended(bool enable);
// Append Log entry
......@@ -302,6 +342,10 @@ protected slots:
void onInputParamChanged();
void onRapidGuideChanged(bool enable);
void setAxisDelta(double ra, double de);
void setAxisSigma(double ra, double de);
void setAxisPulse(double ra, double de);
// FIXME
//void onSetDECSwap(bool enable);
......@@ -363,7 +407,7 @@ private:
QVector3D starCenter;
// Guide Params
double ccd_hor_pixel, ccd_ver_pixel, focal_length, aperture, guideDeviationRA, guideDeviationDEC;
double ccdPixelSizeX, ccdPixelSizeY, mountAperture, mountFocalLength, guideDeviationRA, guideDeviationDEC, pixScaleX, pixScaleY;
// Rapid Guide
bool rapidGuideReticleSet;
......
......@@ -53,6 +53,8 @@ signals:
void newLog(const QString &);
void newStatus(Ekos::GuideState);
void newAxisDelta(double delta_ra, double delta_dec);
void newAxisSigma(double sigma_ra, double sigma_dec);
void newAxisPulse(double pulse_ra, double pulse_dec);
void newStarPosition(QVector3D, bool);
void frameCaptureRequested();
......
......@@ -223,20 +223,17 @@ info_params_t cgmath::getInfoParameters( void ) const
return ret;
}
uint32_t cgmath::getTicks( void ) const
{
return ticks;
}
void cgmath::getStarDrift( double *dx, double *dy ) const
{
*dx = star_pos.x;
*dy = star_pos.y;
}
void cgmath::getStarScreenPosition( double *dx, double *dy ) const
{
*dx = scr_star_pos.x;
......@@ -871,7 +868,7 @@ void cgmath::process_axes( void )
}
emit newAxisDelta(out_params.delta[0], out_params.delta[1]);
//emit newAxisDelta(out_params.delta[0], out_params.delta[1]);
QTextStream out(logFile);
out << ticks << "," << logTime.elapsed() << "," << out_params.delta[0] << "," << out_params.pulse_length[0] << "," << get_direction_string(out_params.pulse_dir[0])
......
......@@ -122,7 +122,7 @@ public:
Matrix getROTZ() { return ROT_Z; }
cproc_in_params *getInputParameters( void );
void setInputParameters( const cproc_in_params *v );
const cproc_out_params *getOutputParameters( void ) const;
const cproc_out_params *getOutputParameters() const { return &out_params; }
info_params_t getInfoParameters( void ) const;
uint32_t getTicks( void ) const;
......
......@@ -28,15 +28,15 @@ InternalGuider::InternalGuider()
// Create math object
pmath = new cgmath();
connect(pmath, SIGNAL(newAxisDelta(double,double)), this, SIGNAL(newAxisDelta(double,double)));
connect(pmath, SIGNAL(newAxisDelta(double,double)), this, SLOT(updateGuideDriver(double,double)));
//connect(pmath, SIGNAL(newAxisDelta(double,double)), this, SIGNAL(newAxisDelta(double,double)));
//connect(pmath, SIGNAL(newAxisDelta(double,double)), this, SLOT(updateGuideDriver(double,double)));
//connect(pmath, SIGNAL(newStarPosition(QVector3D,bool)), this, SLOT(setStarPosition(QVector3D,bool)));
connect(pmath, SIGNAL(newStarPosition(QVector3D,bool)), this, SIGNAL(newStarPosition(QVector3D,bool)));
// Calibration
calibrationStage = CAL_IDLE;
is_started = false;
//is_started = false;
axis = GUIDE_RA;
auto_drift_time = 5;
......@@ -76,6 +76,11 @@ bool InternalGuider::guide()
Options::setDECMinimumPulse(ui.spinBox_MinPulseDEC->value());
#endif
if (state >= GUIDE_GUIDING)
{
return processGuiding();
}
guideFrame->disconnect(this);
//disconnect(guideFrame, SIGNAL(trackingStarSelected(int,int)), 0, 0);
......@@ -145,12 +150,25 @@ bool InternalGuider::guide()
pmath->setLogFile(&logFile);
state = GUIDE_GUIDING;
emit newStatus(state);
emit frameCaptureRequested();
return true;
}
bool InternalGuider::abort()
{
calibrationStage = CAL_IDLE;
if (state == GUIDE_CALIBRATING || state == GUIDE_GUIDING || state == GUIDE_DITHERING)
emit newStatus(GUIDE_ABORTED);
else
emit newStatus(GUIDE_IDLE);
state = GUIDE_IDLE;
return true;
}
......@@ -332,7 +350,7 @@ void InternalGuider::reset()
{
//FIXME
is_started = false;
//is_started = false;
state = GUIDE_IDLE;
//calibrationStage = CAL_IDLE;
connect(guideFrame, SIGNAL(trackingStarSelected(int,int)), this, SLOT(trackingStarSelected(int, int)), Qt::UniqueConnection);
......@@ -855,4 +873,111 @@ bool InternalGuider::setFrameParams(uint16_t x, uint16_t y, uint16_t w, uint16_t
return true;
}
bool InternalGuider::processGuiding()
{
static int maxPulseCounter=0;
const cproc_out_params *out;
QString str;
uint32_t tick = 0;
double drift_x = 0, drift_y = 0;
/*Q_ASSERT( pmath );
if (first_subframe)
{
first_subframe = false;
return;
}
else if (first_frame)
{
if (m_isDithering == false)
{
Vector star_pos = pmath->findLocalStarPosition();
pmath->setReticleParameters(star_pos.x, star_pos.y, -1);
//pmath->moveSquare( round(star_pos.x) - (double)square_size/(2*binx), round(star_pos.y) - (double)square_size/(2*biny) );
}
first_frame=false;
}
*/
// calc math. it tracks square
pmath->performProcessing();
//if(!m_isStarted )
//return true;
if (pmath->isStarLost() && ++m_lostStarTries > 2)
{
emit newLog(i18n("Lost track of the guide star. Try increasing the square size and check the mount."));
abort();
return false;
}
else
m_lostStarTries = 0;
// do pulse
out = pmath->getOutputParameters();
if (out->pulse_length[GUIDE_RA] == Options::rAMaximumPulse() || out->pulse_length[GUIDE_DEC] == Options::dECMaximumPulse())
maxPulseCounter++;
else
maxPulseCounter=0;
if (maxPulseCounter > 3)
{
emit newLog(i18n("Lost track of the guide star. Aborting guiding..."));
abort();
maxPulseCounter=0;
return false;
}
emit newPulse( out->pulse_dir[GUIDE_RA], out->pulse_length[GUIDE_RA], out->pulse_dir[GUIDE_DEC], out->pulse_length[GUIDE_DEC] );
emit frameCaptureRequested();
//if (m_isDithering)
if (state == GUIDE_DITHERING)
return true;
//pmath->getStarDrift( &drift_x, &drift_y );
//drift_graph->add_point( drift_x, drift_y );
tick = pmath->getTicks();
if( tick & 1 )
{
// draw some params in window
emit newAxisDelta(out->delta[GUIDE_RA], out->delta[GUIDE_DEC]);
//ui.l_DeltaRA->setText(str.setNum(out->delta[GUIDE_RA], 'f', 2) );
//ui.l_DeltaDEC->setText(str.setNum(out->delta[GUIDE_DEC], 'f', 2) );
emit newAxisPulse(out->pulse_length[GUIDE_RA], out->pulse_length[GUIDE_DEC]);
//ui.l_PulseRA->setText(str.setNum(out->pulse_length[GUIDE_RA]) );
//ui.l_PulseDEC->setText(str.setNum(out->pulse_length[GUIDE_DEC]) );
//ui.l_ErrRA->setText( str.setNum(out->sigma[GUIDE_RA], 'g', 3));
//ui.l_ErrDEC->setText( str.setNum(out->sigma[GUIDE_DEC], 'g', 3 ));
emit newAxisSigma(out->sigma[GUIDE_RA], out->sigma[GUIDE_DEC]);
}
// skip half frames
//if( half_refresh_rate && (tick & 1) )
//return;
//drift_graph->on_paint();
//pDriftOut->update();
//profilePixmap = pDriftOut->grab(QRect(QPoint(0, 100), QSize(pDriftOut->width(), 101)));
//emit newProfilePixmap(profilePixmap);
return true;
}
}
......@@ -69,8 +69,8 @@ public:
/// IMPORTED CHECK THEM ALL
bool start();
bool abort(bool silence=false);
void setHalfRefreshRate( bool is_half );
//bool abort(bool silence=false);
bool isGuiding( void ) const;
void setAO(bool enable);
void setInterface( void );
......@@ -110,6 +110,14 @@ signals:
void DESwapChanged(bool enable);
private:
// Calibration
void calibrateRADECRecticle( bool ra_only ); // 1 or 2-axis calibration
void processCalibration();
// Guiding
bool processGuiding();
cgmath *pmath;