×

INDI Library v2.0.6 is Released (02 Feb 2024)

Bi-monthly release with minor bug fixes and improvements

Setting exposure impossible with CCD Simulator

  • Posts: 102
  • Thank you received: 13
Dear all,

As usual, I start with thanking developer of Indi, which for me, THE opensource software I was waiting for, in order to make my dream come true : own a robotic observatory.

Although I am used to C++, I decided to go for python, as I would like to focus more on high level scientifi stuff later on.

Unfortunately, I found programming with PyIndi very difficult because of the very sparse documentation, and I found myself unable to find documentation about the various python class available.

Currently, it looks like I cannot launch an exposure on the CCD simulator because of the following error:
[ERROR] Telescope coordinates missing. Make sure telescope is connected and its name is set in CCD Options.

It looks like the super class of CCDSimulator, IndiCCD, has RA and Dec attributes, that should be set ?!
Although I am not sure to understand why, conceptually it is mandatory to know RA and Dec coordinates before perfoming a shoot, I would like to know how could I overcome this problem, for instance by setting a random value to RA/Dec.

I took a look at the Python examples here: indilib.org/support/tutorials/166-instal...on-raspberry-pi.html

And it looks like the ccd device should "snoop" for another device informations :
# Ensure the CCD simulator snoops the telescope simulator
# otherwise you may not have a picture of vega
ccd_active_devices=device_ccd.getText("ACTIVE_DEVICES")
while not(ccd_active_devices):
    time.sleep(0.5)
    ccd_active_devices=device_ccd.getText("ACTIVE_DEVICES")
ccd_active_devices[0].text="Telescope Simulator"
indiclient.sendNewText(ccd_active_devices)

It is still unclear to me why the ccd_active_devices is sent to the indiclient directly, and not the ccd device itself ?
Also, what should I do If I dont have a telescope device connected through indi, for instance If I only want to use Indi to automatize ccd acquisition but not mount related stuff ?

Thank you in advance for your help.
Last edit: 6 years 2 months ago by dolguldur.
6 years 2 months ago #22147

Please Log in or Create an account to join the conversation.

This message is specific to CCD Simulator only. With a regular CCD driver, you can shoot any image and not care about mount coordinates. But since this is a _Simulator_ then it needs to know how to generate the star field. Recently, I added a property to CCD Simulator "EQUATORIAL_PE" with members "RA_PE" and "DEC_PE". You can set those before you capture and you won't get this message. That is, you do not need a mount or mount simulator to listen to.

I hope this explains it. Sorry for the sparse documentation of PyINDI.. we appreciate any help with expand this with more tutorials and examples. If you learn something more from PyINDI and would like to share it in a form of article/tutorial, that would be great. Thanks!
The following user(s) said Thank You: Gebhard, dolguldur
6 years 2 months ago #22157

Please Log in or Create an account to join the conversation.

  • Posts: 102
  • Thank you received: 13
Thank you@knro for your valuable help.
However, it is still very difficult for me to apply your advices:

First I had to check wether the property you were talking about was a switch/text/number, and found answer in the c++ source code: it looks like it is a hierarchical number.
Then I tried to send those to the server and it looks like it did not worked :
2018-01-03T16:55:01: Client 0: read newNumberVector CCD Simulator EQUATORIAL_PE 
      RA_PE='12'
     DEC_PE='45'
2018-01-03T16:55:01: Driver indi_simulator_ccd: queuing responsible for <newNumberVector device='CCD Simulator' name='EQUATORIAL_PE'>
2018-01-03T16:55:01: Driver indi_simulator_ccd: sending msg copy 1 nq 1:
<newNumberVector device="CCD Simulator" name="EQUATORIAL_PE">
    <oneNumber name="RA_PE">
12
    </oneNumber>
    <oneNumber name="DEC_PE">
45
    </oneNumber>
</newNumberVector>
 
2018-01-03T16:55:01: Driver indi_simulator_ccd: read setNumberVector CCD Simulator EQUATORIAL_PE Ok
      RA_PE='12'
     DEC_PE='45'
2018-01-03T16:55:01: Client 0: queuing <setNumberVector device='CCD Simulator' name='EQUATORIAL_PE'>
2018-01-03T16:55:01: Client 0: sending msg copy 1 nq 1:
<setNumberVector device="CCD Simulator" name="EQUATORIAL_PE" state="Ok" timeout="60" timestamp="2018-01-03T16:55:01">
    <oneNumber name="RA_PE">
12
    </oneNumber>
    <oneNumber name="DEC_PE">
45
    </oneNumber>
</setNumberVector>
 
2018-01-03T16:55:01: Client 0: read newNumberVector CCD Simulator CCD_EXPOSURE 
 CCD_EXPOSURE_VALUE='5'
2018-01-03T16:55:01: Driver indi_simulator_ccd: queuing responsible for <newNumberVector device='CCD Simulator' name='CCD_EXPOSURE'>
2018-01-03T16:55:01: Driver indi_simulator_ccd: sending msg copy 1 nq 1:
<newNumberVector device="CCD Simulator" name="CCD_EXPOSURE">
    <oneNumber name="CCD_EXPOSURE_VALUE">
5
    </oneNumber>
</newNumberVector>
 
2018-01-03T16:55:01: Driver indi_simulator_ccd: read message CCD Simulator   '[ERROR] Telescope coordinates missing. Make sure telescope is connected and its name is set in CCD Options.'

What should I do ? (I am using your ppa version of indi for now, and currently retrieving the github version for further investigations)
Last edit: 6 years 2 months ago by dolguldur.
6 years 2 months ago #22180

Please Log in or Create an account to join the conversation.

  • Posts: 102
  • Thank you received: 13
Ok, looking at the code from
libindi/libs/indibase/indiccd.cpp
, I realized that I did not understood your advice:
I added a property to CCD Simulator "EQUATORIAL_PE" with members "RA_PE" and "DEC_PE". You can set those before you capture and you won't get this message

Indeed, lets take a look at my desperate attempt to understand how to assign a simple value to an attribute of a class (ccd simulator driver) using INDI:
cat ./libindi/drivers/ccd/ccd_simulator.cpp | grep RA
 but WITHOUT ANY WARRANTY; without even the implied warranty of
    raPE  = RA;
    IUFillNumber(&SimulatorSettingsN[6], "SIM_SATURATION", "Saturation Mag", "%4.1f", 0, 20, 0, 1.0);
    IUFillNumber(&EqPEN[0], "RA_PE", "RA (hh:mm:ss)", "%010.6m", 0, 24, 0, 0);
    cap |= CCD_CAN_SUBFRAME;
    if (std::isnan(RA) && std::isnan(Dec))
            raPE  = RA;
        INDI::CCDChip::CCD_FRAME ftype = targetChip->getFrameType();
        if (ftype == INDI::CCDChip::LIGHT_FRAME)
        if (ftype == INDI::CCDChip::LIGHT_FRAME || ftype == INDI::CCDChip::FLAT_FRAME)
            if (ftype == INDI::CCDChip::FLAT_FRAME)
            epochPos.ra  = EqPEN[AXIS_RA].value * 15.0;
                if (!strcmp(elemName, "RA_PE"))
                EqPEN[AXIS_RA].value = newra;

Yep absolutely no assignment of a value to RA inside this class., let's take a look at the parent class:
cat ./libindi/libs/indibase/indiccd.cpp | grep RA
 but WITHOUT ANY WARRANTY; without even the implied warranty of
const char *RAPIDGUIDE_TAB     = "Rapid Guide";
    FrameType  = LIGHT_FRAME;
void CCDChip::setFrameType(CCD_FRAME type)
    ImageFrameN[FRAME_X].min = 0;
    ImageFrameN[FRAME_X].max = x - 1;
    ImageFrameN[FRAME_Y].min = 0;
    ImageFrameN[FRAME_Y].max = y - 1;
    ImageFrameN[FRAME_W].min = 1;
    ImageFrameN[FRAME_W].max = x;
    ImageFrameN[FRAME_H].max = 1;
    ImageFrameN[FRAME_H].max = y;
    ImageFrameN[FRAME_X].value = SubX;
    ImageFrameN[FRAME_Y].value = SubY;
    ImageFrameN[FRAME_W].value = SubW;
    ImageFrameN[FRAME_H].value = SubH;
const char *CCDChip::getFrameTypeName(CCD_FRAME fType)
    RA              = std::numeric_limits<double>::quiet_NaN();
    J2000RA         = std::numeric_limits<double>::quiet_NaN();
    IUFillNumber(&TemperatureN[0], "CCD_TEMPERATURE_VALUE", "Temperature (C)", "%5.2f", -50.0, 50.0, 0., 0.);
    IUFillNumberVector(&TemperatureNP, TemperatureN, 1, getDeviceName(), "CCD_TEMPERATURE", "Temperature",
    IUFillNumberVector(&PrimaryCCD.ImageFrameNP, PrimaryCCD.ImageFrameN, 4, getDeviceName(), "CCD_FRAME", "Frame",
    IUFillSwitch(&PrimaryCCD.FrameTypeS[0], "FRAME_LIGHT", "Light", ISS_ON);
    IUFillSwitch(&PrimaryCCD.FrameTypeS[1], "FRAME_BIAS", "Bias", ISS_OFF);
    IUFillSwitch(&PrimaryCCD.FrameTypeS[2], "FRAME_DARK", "Dark", ISS_OFF);
    IUFillSwitch(&PrimaryCCD.FrameTypeS[3], "FRAME_FLAT", "Flat", ISS_OFF);
    IUFillSwitchVector(&PrimaryCCD.FrameTypeSP, PrimaryCCD.FrameTypeS, 4, getDeviceName(), "CCD_FRAME_TYPE",
    IUFillSwitch(&PrimaryCCD.CompressS[1], "CCD_RAW", "Raw", ISS_ON);
    IUFillSwitchVector(&PrimaryCCD.ResetSP, PrimaryCCD.ResetS, 1, getDeviceName(), "CCD_FRAME_RESET", "Frame Values",
    IUFillSwitchVector(&PrimaryCCD.RapidGuideSP, PrimaryCCD.RapidGuideS, 2, getDeviceName(), "CCD_RAPID_GUIDE",
                       "CCD_RAPID_GUIDE_SETUP", "Rapid Guide Setup", RAPIDGUIDE_TAB, IP_RW, ISR_NOFMANY, 0, IPS_IDLE);
                       "CCD_RAPID_GUIDE_DATA", "Rapid Guide Data", RAPIDGUIDE_TAB, IP_RO, 60, IPS_IDLE);
    IUFillNumberVector(&GuideCCD.ImageFrameNP, GuideCCD.ImageFrameN, 4, getDeviceName(), "GUIDER_FRAME", "Frame",
    IUFillSwitch(&GuideCCD.FrameTypeS[0], "FRAME_LIGHT", "Light", ISS_ON);
    IUFillSwitch(&GuideCCD.FrameTypeS[1], "FRAME_BIAS", "Bias", ISS_OFF);
    IUFillSwitch(&GuideCCD.FrameTypeS[2], "FRAME_DARK", "Dark", ISS_OFF);
    IUFillSwitch(&GuideCCD.FrameTypeS[3], "FRAME_FLAT", "Flat", ISS_OFF);
    IUFillSwitchVector(&GuideCCD.FrameTypeSP, GuideCCD.FrameTypeS, 4, getDeviceName(), "GUIDER_FRAME_TYPE",
    IUFillSwitch(&GuideCCD.CompressS[1], "GUIDER_RAW", "Raw", ISS_ON);
    IUFillSwitchVector(&GuideCCD.RapidGuideSP, GuideCCD.RapidGuideS, 2, getDeviceName(), "GUIDER_RAPID_GUIDE",
                       "GUIDER_RAPID_GUIDE_SETUP", "Rapid Guide Setup", RAPIDGUIDE_TAB, IP_RW, ISR_NOFMANY, 0,
                       "GUIDER_RAPID_GUIDE_DATA", "Rapid Guide Data", RAPIDGUIDE_TAB, IP_RO, 60, IPS_IDLE);
    // Snooped RA/DEC Property
    IUFillNumber(&EqN[0], "RA", "Ra (hh:mm:ss)", "%010.6m", 0, 24, 0, 0);
    IDSnoopDevice(ActiveDeviceT[SNOOP_MOUNT].text, "GEOGRAPHIC_COORD");
        if ((newra != RA) || (newdec != Dec))
            //IDLog("RA %4.2f  Dec %4.2f Snooped RA %4.2f  Dec %4.2f\n",RA,Dec,newra,newdec);
            RA  = newra;
    else if (!strcmp(propName, "GEOGRAPHIC_COORD"))
                IDSnoopDevice(ActiveDeviceT[SNOOP_MOUNT].text, "GEOGRAPHIC_COORD");
                RA = std::numeric_limits<double>::quiet_NaN();
                J2000RA = std::numeric_limits<double>::quiet_NaN();
            if (PrimaryCCD.getFrameType() != CCDChip::BIAS_FRAME &&
            if (PrimaryCCD.getFrameType() == CCDChip::BIAS_FRAME)
                if (PrimaryCCD.getFrameType() == CCDChip::LIGHT_FRAME && !std::isnan(RA) && !std::isnan(Dec))
                    epochPos.ra  = RA * 15.0;
                    J2000RA = J2000Pos.ra / 15.0;
            if (GuideCCD.getFrameType() != CCDChip::BIAS_FRAME &&
            if (GuideCCD.getFrameType() == CCDChip::BIAS_FRAME)
        if (!strcmp(name, "CCD_FRAME"))
        if (!strcmp(name, "GUIDER_FRAME"))
        // CCD TEMPERATURE:
                PrimaryCCD.setFrameType(CCDChip::LIGHT_FRAME);
                PrimaryCCD.setFrameType(CCDChip::BIAS_FRAME);
                PrimaryCCD.setFrameType(CCDChip::DARK_FRAME);
                PrimaryCCD.setFrameType(CCDChip::FLAT_FRAME);
                GuideCCD.setFrameType(CCDChip::LIGHT_FRAME);
                GuideCCD.setFrameType(CCDChip::BIAS_FRAME);
                GuideCCD.setFrameType(CCDChip::DARK_FRAME);
                GuideCCD.setFrameType(CCDChip::FLAT_FRAME);
bool CCD::UpdateCCDFrameType(CCDChip::CCD_FRAME fType)
bool CCD::UpdateGuiderFrameType(CCDChip::CCD_FRAME fType)
        case CCDChip::LIGHT_FRAME:
        case CCDChip::BIAS_FRAME:
        case CCDChip::FLAT_FRAME:
        case CCDChip::DARK_FRAME:
    if (targetChip->getFrameType() == CCDChip::DARK_FRAME)
    fits_update_key_s(fptr, TSTRING, "FRAME", frame_s, "Frame Type", &status);
    if (targetChip->getFrameType() == CCDChip::LIGHT_FRAME && !std::isnan(J2000RA) && !std::isnan(J2000DE))
        fs_sexa(ra_str, J2000RA, 2, 360000);
        fits_update_key_s(fptr, TSTRING, "OBJCTRA", ra_str, "Object RA", &status);
            double J2000RAHours = J2000RA * 15;
            fits_update_key_s(fptr, TDOUBLE, "CRVAL1", &J2000RAHours, "CRVAL1", &status);
            char ctype1[16]  = "RA---TAN";
            fits_update_key_s(fptr, TSTRING, "RADECSYS", radecsys, "RADECSYS", &status);
                if (targetChip->getFrameType() == CCDChip::LIGHT_FRAME && !std::isnan(RA) && !std::isnan(Dec))
                    epochPos.ra  = RA * 15.0;
                    J2000RA = J2000Pos.ra / 15.0;

Ok, then only one non trivial assignment to RA which is:
bool CCD::ISSnoopDevice(XMLEle *root)
{
    XMLEle *ep           = nullptr;
    const char *propName = findXMLAttValu(root, "name");
 
    if (IUSnoopNumber(root, &EqNP) == 0)
    {
        float newra, newdec;
        newra  = EqN[0].value;
        newdec = EqN[1].value;
        if ((newra != RA) || (newdec != Dec))
        {
            //IDLog("RA %4.2f  Dec %4.2f Snooped RA %4.2f  Dec %4.2f\n",RA,Dec,newra,newdec);
            RA  = newra;
            Dec = newdec;
        }
    }

Here I am completely lost with this snooping mechanism...
In my understanding, one should register a listening and listened device driver to the indi server, and whenever indiserver sees something sent from the listened driver, it sends it to the listening driver ?
Am I right ?

Am I also right saying that it is impossible to 'simulate' this snooping behaviour by just sending the right property to the driver of interested (ccd simulator in our case) ?

Thank you in advance for your help.
Last edit: 6 years 2 months ago by dolguldur.
6 years 2 months ago #22183

Please Log in or Create an account to join the conversation.

I made a simple change to fix this, please try again with tomorrow PPA or compile INDI from source now to get the fix.
6 years 2 months ago #22186

Please Log in or Create an account to join the conversation.

  • Posts: 102
  • Thank you received: 13
I tried with the latest version, but unfortunately, I still get the same error, after setting EQ PE in Simulator config
6 years 2 months ago #22187

Please Log in or Create an account to join the conversation.

How did you try? PPA version is built daily, so it will be available tomorrow, not now. Or you compiled from GIT?
The following user(s) said Thank You: dolguldur
6 years 2 months ago #22188

Please Log in or Create an account to join the conversation.

  • Posts: 102
  • Thank you received: 13
Right ! I am sorry for my last message, what happened is that I had multiple indi binary on my system, and I was launching
instead of
./indiserver -vvv ./indi_simulator_ccd

Now the error is gone, and I can resume my current work.
But I am still interested in any ressource that would help me to undersand the snooping mechanism.
Last edit: 6 years 2 months ago by dolguldur.
6 years 2 months ago #22189

Please Log in or Create an account to join the conversation.

Time to create page: 0.413 seconds