Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue705(part of the issue): Added Altitude and Azimuth to TelescopeTCP class #3626

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 62 additions & 5 deletions plugins/TelescopeControl/src/TelescopeClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "INDI/TelescopeClientINDI.hpp"
#include "StelTranslator.hpp"
#include "StelCore.hpp"
#include "StelUtils.hpp"

#include <cmath>

Expand Down Expand Up @@ -125,6 +126,31 @@ TelescopeClient *TelescopeClient::create(const QString &url)
TelescopeClient::TelescopeClient(const QString &name) : nameI18n(name), name(name)
{}


bool TelescopeClient::GetAltAzFromJ2000Position(const Vec3d &j2000Pos,TelescopeControl::Equinox equinox ,double& alt, double &az) const
{
const StelCore* core = StelApp::getInstance().getCore();
const bool res = core != nullptr;
if(res)
{
const bool equinoxJNow = equinox == TelescopeControl::EquinoxJNow;
const StelCore::RefractionMode mode = equinoxJNow ? StelCore::RefractionOff : StelCore::RefractionAuto;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The necessity for refraction correction should depend on atmosphere visibility. It has nothing to do with JNow setting. What is your motivation to connect them?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I'm not sure what it is used for. The reason I have this check is because I saw in the TelescopeGoTo method that it was used to correct the J2000 position. See line 300-304:
image

Is there a way to check for atmosphere visilibility. And if so should it also be used in the screenshot above?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, when driving a telescope from a terrestrial location, it is safe to assume (the real, physical) atmosphere (in which we breathe) is on.

If you have "pure" J2000 data from a catalog/ephemeris (without refraction correction), You must convert them to JNow equatorial position without refraction correction (core->j2000ToEquinoxEqu(j2000Pos, RefractionOff) when the telescope expects that (and applies refraction correction internally).

Then, to compute geometrical Alt-Az position for a goto capable device, you compute alt-az position (core->j2000ToAltAz(positionJ2000, refractionMode);) If your telescope expects AltAz coordinates to be corrected for refraction, you should compute with RefractionOn. If your telescope expects AltAz position to be without refraction correction (because it will do that by itself!), you use RefractionOff.

I have never used an alt-az GOTO telescope, so I am not familiar with these protocols. Maybe this needs yet another config option ("Goto is AzAlt and expects/does not expect refraction correction") Does such a device track the object after the goto slew? Why not just send RA/Dec to a properly configured/set up mount?

Copy link
Author

@huntflex huntflex Feb 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that my own Eq6-r pro does refraction correction based on the elevation you input. I don't know about other mounts.
Seeing that the class I'm extending is the TelescopeTCP class which is most likely used for (I asumme??) for a homemade telescope control system maybe it would be wise to have these options under the Telescope properties when you set up the host.

For example:
image

What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably the Boolean JNow setting will have to be extended to a 3-value J2000/JNow/AltAz, and an additional Boolean RefractionCorrection would govern the independent extra. @alex-w ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alex-w I wanted to extend the relevant telescope classes with altitude azimuth. I thought a natural (and easier place) to begin with would be the telescopeTCP class. As you know the TelescopeTCP class is the one instantiated whenever a user configures a telescope with a "remote computer". I assumed that one would also want access to alt/az in this kind of setup since a "remote computer" might not be limited to an equatorial mount.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the mount can be AltAz-only and I fear these mounts will not understand some parts of protocol. Plus EQ/AltAz-mount requires setting the mode. In both cases changes of protocols can be for first item only - commnication directly through a serial port. The second item is incompatible now (I really don't know modern use cases for old Stellarium protocol for mounts - a TelescopeServer).

What about real hardware - is it working in AltAz mode?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be useful for DIY projects with self-made controllers (e.g. Arduino, self-made axis decoder/motor protocol, ...). But I have never used the telescopeTCP stuff, so I cannot say how relevant this still is.
The docs in TelescopeClient.hpp indicate a "Stellarium telescope control protocol" to be included in "telescope server software". Where is this all? (Yes, Google found a 1-page file from J.G. on some "free" site.) Is/Was that a reference implementation of something useful? Then it should probably be archived in a repo here. And somebody who was involved should write the design docs to explain it all. (OK, dreaming...)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first version of TelescopeServer is located in SourceForge (SVN: https://sourceforge.net/p/stellarium/code/HEAD/tree/trunk/), the second version is in GitHub: https://github.com/johannesgajdosik/TelescopeServer2

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I'm wondering if this is the right course of action with this patch. Whether we should continue with this PR?

const Vec3d positionJ2000 = equinoxJNow ? core->j2000ToEquinoxEqu(j2000Pos,mode) : j2000Pos;

const Vec3d position_alt_az = core->j2000ToAltAz(positionJ2000,mode);
StelUtils::rectToSphe(&az,&alt,position_alt_az);

const bool useSouthAzimuth = StelApp::getInstance().getFlagSouthAzimuthUsage();
const double direction = useSouthAzimuth ? 2. : 3.; // N is zero, E is 90 degrees
az = direction*M_PI - az;
if (az > M_PI*2.0)
{
az -= M_PI*2.0;
}
}
return res;
}

QString TelescopeClient::getInfoString(const StelCore* core, const InfoStringGroup& flags) const
{
QString str;
Expand Down Expand Up @@ -258,6 +284,7 @@ void TelescopeTCP::hangup(void)
interpolatedPosition.reset();
}


//! queues a GOTO command with the specified position to the write buffer.
//! For the data format of the command see the
//! "Stellarium telescope control protocol" text file
Expand All @@ -269,22 +296,36 @@ void TelescopeTCP::telescopeGoto(const Vec3d &j2000Pos, StelObjectP selectObject
return;

Vec3d position = j2000Pos;

if (equinox == TelescopeControl::EquinoxJNow)
{
const StelCore* core = StelApp::getInstance().getCore();
position = core->j2000ToEquinoxEqu(j2000Pos, StelCore::RefractionOff);
}

if (writeBufferEnd - writeBuffer + 20 < static_cast<int>(sizeof(writeBuffer)))

if (writeBufferEnd - writeBuffer + packetLength < static_cast<int>(sizeof(writeBuffer)))
{
const double ra_signed = atan2(position[1], position[0]);
//Workaround for the discrepancy in precision between Windows/Linux/PPC Macs and Intel Macs:
const double ra = (ra_signed >= 0) ? ra_signed : (ra_signed + 2.0 * M_PI);
const double dec = atan2(position[2], std::sqrt(position[0]*position[0]+position[1]*position[1]));
unsigned int ra_int = static_cast<unsigned int>(std::floor(0.5 + ra*((static_cast<unsigned int>(0x80000000))/M_PI)));
int dec_int = static_cast<int>(std::floor(0.5 + dec*((static_cast<unsigned int>(0x80000000))/M_PI)));
// length of packet:
*writeBufferEnd++ = 20;
unsigned int ra_int = static_cast<unsigned int>(std::floor(0.5 + ra*((static_cast<unsigned int>(0x80000000))/M_PI)));
int dec_int = static_cast<int>(std::floor(0.5 + dec*((static_cast<unsigned int>(0x80000000))/M_PI)));

double azimuth = 0.0;
double altitude = 0.0;
if(!GetAltAzFromJ2000Position(j2000Pos,equinox,altitude,azimuth))
{
qDebug() << "TelescopeTCP(" << name << ")::telescopeGoto: "<< ""
"unable to convert j2000 position to alt az.";
}

unsigned int az_int = static_cast<unsigned int>(std::floor(0.5 + azimuth*((static_cast<unsigned int>(0x80000000)/M_PI))));
int alt_int = static_cast<int>(std::floor(0.5 + altitude*((static_cast<unsigned int>(0x80000000)/M_PI))));

// length of packet:
*writeBufferEnd++ = packetLength;
*writeBufferEnd++ = 0;
// type of packet:
*writeBufferEnd++ = 0;
Expand Down Expand Up @@ -322,6 +363,22 @@ void TelescopeTCP::telescopeGoto(const Vec3d &j2000Pos, StelObjectP selectObject
*writeBufferEnd++ = static_cast<char>(dec_int & 0xFF);
dec_int>>=8;
*writeBufferEnd++ = static_cast<char>(dec_int & 0xFF);
//alt
*writeBufferEnd++ = static_cast<char>(alt_int & 0xFF);
alt_int>>=8;
*writeBufferEnd++ = static_cast<char>(alt_int & 0xFF);
alt_int>>=8;
*writeBufferEnd++ = static_cast<char>(alt_int & 0xFF);
alt_int>>=8;
*writeBufferEnd++ = static_cast<char>(alt_int & 0xFF);
//az
*writeBufferEnd++ = static_cast<char>(az_int & 0xFF);
az_int>>=8;
*writeBufferEnd++ = static_cast<char>(az_int & 0xFF);
az_int>>=8;
*writeBufferEnd++ = static_cast<char>(az_int & 0xFF);
az_int>>=8;
*writeBufferEnd++ = static_cast<char>(az_int & 0xFF);
}
else
{
Expand Down
14 changes: 12 additions & 2 deletions plugins/TelescopeControl/src/TelescopeClient.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,17 @@ class TelescopeClient : public QObject, public StelObject
QString nameI18n;
const QString name;

virtual QString getTelescopeInfoString(const StelCore* core, const InfoStringGroup& flags) const
/*!
* \brief Get the alt/az in rad from the j2000 position
* \param j2000Pos
* \param equinox
* \param alt [out]
* \param az [out]
* \return true/false if successful or not
*/
bool GetAltAzFromJ2000Position(const Vec3d &j2000Pos,TelescopeControl::Equinox equinox,double& alt, double &az) const;

virtual QString getTelescopeInfoString(const StelCore* core, const InfoStringGroup& flags) const
{
Q_UNUSED(core)
Q_UNUSED(flags)
Expand Down Expand Up @@ -231,7 +241,7 @@ class TelescopeTCP : public TelescopeClient
char writeBuffer[120];
char *writeBufferEnd;
int time_delay;

static constexpr int packetLength{28};
InterpolatedPosition interpolatedPosition;
bool hasKnownPosition(void) const override
{
Expand Down
Loading