×

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

Bi-monthly release with minor bug fixes and improvements

Dithering is not executed with external lin_guider

Transient timing issues are hard to track down, but if you turn on logging it might help us somehow. Of course, if you can debug and find out where it gets stuck exactly that would be great.
7 years 2 weeks ago #15083

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

  • Posts: 79
  • Thank you received: 23
Hi guys,
where are problems #14978 and #14929 described?

What comes to the return "OK" fix it can not be accepted for several reasons.
First there are several pieces of software relaying on that and we can not change it, so it should be changed on Ekos side. Second dither command is not recommended as you have no idea if it was successful or not. That is why it does not say OK or Error. It is kept only for compatibility purposes. There is another non-blocking command for dithering: DITHER_NO_WAIT_XY. It returns immediately and if successful you can check if it is completed or not with GET_DISTANCE which will give you the distance between the target and current position.
What is problem #14978? :) I do not see it anywhere...
Rumen
Last edit: 7 years 2 weeks ago by rumen.
7 years 2 weeks ago #15088

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

  • Posts: 48
  • Thank you received: 7
Hi, rumen.
Thank you for detailed explanation.
I understood the specification of lin_guider.
It is said that the response of the DITHER command does not inform of the success of dithering.
I will undo my modifications.
Then fix it so that Ekos ignores the response of the DITHER command and try it.

I am debugging Kstars on communication with lin_guider.
I will report when I found something.
7 years 2 weeks ago #15103

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

  • Posts: 79
  • Thank you received: 23
Hi,
if you are willing it is better to use the commands I have mentioned. It is not that simple with DITHER command, What this command does is do the DITHER wait some amount of time calculated by the guide rate and the dithering range and return. However if the calibration is not performed it will fail with "Error:..." or if in progress with "Busy:...". These are precondition checks. So you can not ignore the output. However there is no way to be sure if it is finished successfully or not if it started it will just wait some time and return amusing that the mount is settled. So I was not precise in my previous post. You can be sure if it says "Error" or "Busy" that that it did not succeed, but there is no way to be sure if it really succeeded, however you can safely assume success if it does not say Busy and Error.
Best way is to use DITHER_NO_WAIT_XY, and poll while GET_DISTANCE returns values within a specified range.

Rumen

p.s. Lin-guider is close to 4.2.0 with driver updates and zoom of the image view, Also there may be SBIG camera support but most likely it will wait for 4.3 as I do not have much time for that now.
Last edit: 7 years 2 weeks ago by rumen.
7 years 2 weeks ago #15104

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

  • Posts: 48
  • Thank you received: 7
Thanks for your advice.It will be helpful.
Lin_guider is very lightweight and easy to use, so I like it very much.
I am looking forward to the new version.
7 years 2 weeks ago #15119

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

  • Posts: 48
  • Thank you received: 7
I looked at the debug output of Ekos.

When I dumped the response from lin_guider I noticed that I was receiving an irregular data stream.
A sample of the received data stream is as follows.
Guide: "\u0002\u0000\u000E\u0000\u000B\u0000\u0000\u0000-0.43 -0.02"
Guide: "\u0002\u0000\u000E\u0000\u0000\u0000\u0000-0.37 0.51"
Guide: "\u0002\u0000\r\u0000\u0002\u0000\u0000\u0000OK"
Guide:  "LinGuider::processResponse SET_DITHERING_RANGE"
Guide: "\u0002\u0000\u000E\u0000\u000B\u0000\u0000\u0000-1.37 -0.32"
Guide: "\u0002\u0000\u0004\u0000\u0002\u0000\u0000\u0000OK"
Guide:  "LinGuider::processResponse DITHERING"
Guide:  "Dithering completed successfully."
Guide:  "Guiding resumed."
Guide: Capturing frame...
Guide: "\u0002\u0000\u000E\u0000\t\u0000\u0000\u00000.03 0.87"
Guide: "\u0002\u0000\u000E\u0000\t\u0000\u0000\u00000.49 0.85"
Guide: "\u0002\u0000\r\u0000\u0002\u0000\u0000\u0000OK\u0002\u0000\u000E\u0000"
Guide:  "LinGuider::processResponse SET_DITHERING_RANGE"
Guide:  "Failed to set dither range."
Guide: "\u0000\u0000\u0000-0.27 0.64"
Guide:  "Invalid response."
Guide: "\u0002\u0000\u000E\u0000\t\u0000\u0000\u00000.14 0.63"
Guide: "\u0002\u0000\u000E\u0000\u000B\u0000\u0000\u0000-0.19 -0.86"
Guide: "\u0002\u0000\u000E\u0000\u000B\u0000\u0000\u0000-0.31 -0.49\u0002\u0000\r\u0000\u0002\u0000\u0000\u0000OK"
Guide: "\u0002\u0000\u000E\u0000\u000B\u0000\u0000\u0000-0.31 -0.49"

A normal response is:
Guide: "\u0002\u0000\u000E\u0000\u000B\u0000\u0000\u0000-0.43 -0.02"
Convert to byte sequence:
0x02 0x00 0x0e 0x00 0x0b 0x00 0x00 0x00 "-0.43 -0.02"
It has an 8-byte header and text data.


It shows a pattern of irregular response.
Guide: "\u0002\u0000\u000E\u0000\u000B\u0000\u0000\u0000-0.31 -0.49\u0002\u0000\r\u0000\u0002\u0000\u0000\u0000OK"
Convert to byte sequence:
0x02 0x00 0x0e 0x00 0x0b 0x00 0x00 0x00 "-0.31 -0.49" 0x02 0x00 0x0d 0x00 0x02 0x00 0x00 0x00 "OK"
The two command responses are consecutive.

Another pattern is:
Guide: "\u0002\u0000\r\u0000\u0002\u0000\u0000\u0000OK\u0002\u0000\u000E\u0000"
Convert to byte sequence:
0x02 0x00 0x0d 0x00 0x02 0x00 0x00 0x00 "OK" 0x02 0x00 0x0e 0x00
After the normal command response, the next command response fragment "0x02 0x00 0x0e 0x00" is attached.


Responses from lin_guider are handled by LinGuider::readLinGuider().
The response is read and processed from the socket using QTextStream, but it is assumed that it receives one command response from lin_guider.
It can not be handled correctly if multiple command responses receive consecutive data streams or responses with fragments.

This problem is unlikely to occur in high-speed network, high-speed CPU environment.
However, there is a possibility of occurrence in any network.

There is also a command response in which the header is broken.
For example,
Guide: "\u0002\u0000\u000E\u0000\u0000\u0000\u0000-0.02 0.90"
Convert to byte sequence:
0x02 0x00 0x0e 0x00 0x00 0x00 0x00 "-0.02 0.90"

There is only 7 bytes of header, and there is no length of text data.
Is the CRLF code (0x0d / 0x0a) automatically removed by QTextStream?
The following user(s) said Thank You: Jasem Mutlaq
7 years 2 weeks ago #15120

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

  • Posts: 79
  • Thank you received: 23
Hi,
One can not expect that separate TCP packets will be read in separate reads. It is a stream so it should be read as a stream too. Reading should be done as follows: read the first 2 bytes (used as linguider identifier) read next 2 bytes (command ID) and next 4 as length, then read "length" bytes and use them as command response. then next should be linguider ID and so on...

I am not an expert in the thousands of the QT classes but the name QTextStream suggests that it is not a raw stream but text stream. Also if readLine is used it removes \n and \r. the last resonance has length 10 which is "\n" and is obviously removed.

So looks like this part should be reworked

Rumen
Last edit: 7 years 2 weeks ago by rumen.
7 years 2 weeks ago #15127

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

Thanks noriq for the details. Ok it can be read as raw data. Try to do this.
while (tcpSocket->atEnd() == false)
{
QByteArray data = tcpSocket->read( 8 );
....etc
}

then process the data. Try to see if that works
Last edit: 7 years 2 weeks ago by Jasem Mutlaq.
7 years 2 weeks ago #15142

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

  • Posts: 48
  • Thank you received: 7
Hi, knro.
You are welcome. Thanks for the hint.
I modified it using raw data as you suggested.
This is going very well.

The patch is as follows.
/kstars/ekos/guide/externalguide/linguider.h
 private:
     void sendCommand(LinGuiderCommand command, const QString &args = QString());
     void processResponse(LinGuiderCommand command, const QString &reply);
 
     QTcpSocket *tcpSocket;
+    QByteArray rawBuffer;

/kstars/ekos/guide/externalguide/linguider.cpp
 LinGuider::LinGuider()
 {
+    rawBuffer.clear();
     tcpSocket = new QTcpSocket(this);
 
 
 
 bool LinGuider::Connect()
 {
     if (connection == DISCONNECTED)
     {
+        rawBuffer.clear();
         connection = CONNECTING;
 
 
 bool LinGuider::Disconnect()
 {  
+    rawBuffer.clear();
     connection = DISCONNECTED;
     tcpSocket->disconnectFromHost();
 
 
 
void LinGuider::readLinGuider()
{
    while (tcpSocket->atEnd() == false )
    {
        rawBuffer += tcpSocket->readAll();
 
        while(1)
        {
            if (rawBuffer.count() < 8)
                break;
 
            if (Options::guideLogging())
                qDebug() << "Guide:" << rawBuffer;
 
            qint16 magicNumber = *(reinterpret_cast<qint16*>(rawBuffer.data()));
            if (magicNumber != 0x02)
            {
                emit newLog(i18n("Invalid response."));
                rawBuffer = rawBuffer.mid(1);
                continue;
            }
 
            qint16 command = *(reinterpret_cast<qint16*>(rawBuffer.data()+2));
            if (command < GET_VER || command > GET_RA_DEC_DRIFT)
            {
                emit newLog(i18n("Invalid response."));
                rawBuffer = rawBuffer.mid(1);
                continue;
            }
 
            qint16 datalen = *(reinterpret_cast<qint16*>(rawBuffer.data()+4));
            if (rawBuffer.count() < datalen + 8)
                break;
 
            QString reply = rawBuffer.mid(8, datalen);
            processResponse(static_cast<LinGuiderCommand>(command), reply);
            rawBuffer = rawBuffer.mid(8+datalen);
        }
    }
}
 

To solve multiple command responses and fragments, I added a buffer using QByteArray as a private member of the LinGuider class.
And, I rewrote LinGuider::readLinGuider().

Also, I modified LinGuider::processResponse ().
 void LinGuider::processResponse(LinGuiderCommand command, const QString &reply)
 {
 :
     case DITHER:
-        if (reply == "OK")
+        if (reply == "Long time cmd finished")
            emit newStatus(GUIDE_DITHERING_SUCCESS);
        else
            emit newStatus(GUIDE_DITHERING_ERROR);
This fix is not the best, but it is necessary for dithering to work for the time being.
A better answer is as proposed by rumen.
7 years 2 weeks ago #15144

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

  • Posts: 79
  • Thank you received: 23
For those who are interested Lin-guider 4.2.0 is released today :)
It can zoom images for viewing in real time and ZWO ASI and Atik drivers are improved.

best
Rumen
The following user(s) said Thank You: Jasem Mutlaq, Andrew, norikyu
7 years 5 days ago #15532

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

  • Posts: 48
  • Thank you received: 7
Hello rumen.
Thank you for the new lin_guider announcement.

I tried dithering with a combination of lin_guider 4.2.0 and kstars 2.7.6.
It worked so perfectly!
I appreciate lin_guider and ekos, two great software.
Thank you.
7 years 2 days ago #15666

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

Time to create page: 4.589 seconds