TelescopeClient.cpp   TelescopeClient.cpp 
skipping to change at line 51 skipping to change at line 51
#include <QTextStream> #include <QTextStream>
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
#include <windows.h> // GetSystemTimeAsFileTime() #include <windows.h> // GetSystemTimeAsFileTime()
#else #else
#include <sys/time.h> #include <sys/time.h>
#endif #endif
TelescopeClient *TelescopeClient::create(const QString &url) TelescopeClient *TelescopeClient::create(const QString &url)
{ {
// example url: My_first_telescope:TCP:localhost:10000:500000 // example url: My_first_telescope:TCP:J2000:localhost:10000:500000
// split to: // split to:
// name = My_first_telescope // name = My_first_telescope
// type = TCP // type = TCP
// equinox = J2000
// params = localhost:10000:500000 // params = localhost:10000:500000
// //
// The params part is optional. We will use QRegExp to validate // The params part is optional. We will use QRegExp to validate
// the url and extact the components. // the url and extact the components.
// note, in a reg exp, [^:] matches any chararacter except ':' // note, in a reg exp, [^:] matches any chararacter except ':'
QRegExp recRx("^([^:]*):([^:]*)(:(.*))?$"); QRegExp urlSchema("^([^:]*):([^:]*):([^:]*)(?::(.*))?$");
QString name, type, params; QString name, type, equinox, params;
if (recRx.exactMatch(url)) if (urlSchema.exactMatch(url))
{ {
// trimmed removes whitespace on either end of a QString // trimmed removes whitespace on either end of a QString
name = recRx.capturedTexts().at(1).trimmed(); name = urlSchema.capturedTexts().at(1).trimmed();
type = recRx.capturedTexts().at(2).trimmed(); type = urlSchema.capturedTexts().at(2).trimmed();
params = recRx.capturedTexts().at(4).trimmed(); equinox = urlSchema.capturedTexts().at(3).trimmed();
params = urlSchema.capturedTexts().at(4).trimmed();
} }
else else
{ {
qWarning() << "WARNING - telescope definition" << url << "no t recognised"; qWarning() << "WARNING - telescope definition" << url << "no t recognised";
return NULL; return NULL;
} }
qDebug() << "Creating telescope" << url << "; name/type/params:" << Equinox eq = EquinoxJ2000;
name << type << params; if (equinox == "JNow")
eq = EquinoxJNow;
qDebug() << "Creating telescope" << url << "; name/type/equinox/para
ms:" << name << type << ((eq == EquinoxJNow) ? "JNow" : "J2000") << params;
TelescopeClient * newTelescope = 0; TelescopeClient * newTelescope = 0;
//if (type == "Dummy") //if (type == "Dummy")
if (type == "TelescopeServerDummy") if (type == "TelescopeServerDummy")
{ {
newTelescope = new TelescopeClientDummy(name, params); newTelescope = new TelescopeClientDummy(name, params);
} }
else if (type == "TCP") else if (type == "TCP")
{ {
newTelescope = new TelescopeTCP(name, params); newTelescope = new TelescopeTCP(name, params, eq);
} }
else if (type == "TelescopeServerLx200") //BM: One of the rare occas ions of painless extension else if (type == "TelescopeServerLx200") //BM: One of the rare occas ions of painless extension
{ {
newTelescope= new TelescopeClientDirectLx200(name, params); newTelescope= new TelescopeClientDirectLx200(name, params, e q);
} }
else if (type == "TelescopeServerNexStar") else if (type == "TelescopeServerNexStar")
{ {
newTelescope= new TelescopeClientDirectNexStar(name, params) ; newTelescope= new TelescopeClientDirectNexStar(name, params, eq);
} }
else else
{ {
qWarning() << "WARNING - unknown telescope type" << type << "- not creating a telescope object for url" << url; qWarning() << "WARNING - unknown telescope type" << type << "- not creating a telescope object for url" << url;
} }
if (newTelescope && !newTelescope->isInitialized()) if (newTelescope && !newTelescope->isInitialized())
{ {
qDebug() << "TelescopeClient::create(): Unable to create a t elescope client."; qDebug() << "TelescopeClient::create(): Unable to create a t elescope client.";
delete newTelescope; delete newTelescope;
skipping to change at line 151 skipping to change at line 157
FILETIME file_time; FILETIME file_time;
GetSystemTimeAsFileTime(&file_time); GetSystemTimeAsFileTime(&file_time);
return (*((__int64*)(&file_time))/10) - 86400000000LL*134774; return (*((__int64*)(&file_time))/10) - 86400000000LL*134774;
#else #else
struct timeval tv; struct timeval tv;
gettimeofday(&tv,0); gettimeofday(&tv,0);
return tv.tv_sec * 1000000LL + tv.tv_usec; return tv.tv_sec * 1000000LL + tv.tv_usec;
#endif #endif
} }
TelescopeTCP::TelescopeTCP(const QString &name, const QString &params) : TelescopeTCP::TelescopeTCP(const QString &name, const QString &params, Equi
TelescopeClient(name), nox eq) :
tcpSocket(new QTcpSocket()), TelescopeClient(name),
end_position(positions+(sizeof(positions)/sizeof tcpSocket(new QTcpSocket()),
(positions[0]))) equinox(eq)
{ {
hangup(); hangup();
// Example params: // Example params:
// localhost:10000:500000 // localhost:10000:500000
// split into: // split into:
// host = localhost // host = localhost
// port = 10000 (int) // port = 10000 (int)
// time_delay = 500000 (int) // time_delay = 500000 (int)
skipping to change at line 222 skipping to change at line 228
} }
} }
if(address.isNull()) if(address.isNull())
{ {
qWarning() << "ERROR creating TelescopeTCP: cannot find IPv4 address. Addresses found at " << host << ":" << info.addresses(); qWarning() << "ERROR creating TelescopeTCP: cannot find IPv4 address. Addresses found at " << host << ":" << info.addresses();
return; return;
} }
end_of_timeout = -0x8000000000000000LL; end_of_timeout = -0x8000000000000000LL;
resetPositions(); interpolatedPosition.reset();
connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this , SLOT(socketFailed(QAbstractSocket::SocketError))); connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this , SLOT(socketFailed(QAbstractSocket::SocketError)));
} }
void TelescopeTCP::hangup(void) void TelescopeTCP::hangup(void)
{ {
if (tcpSocket->isValid()) if (tcpSocket->isValid())
{ {
tcpSocket->abort();// Or maybe tcpSocket->close()? tcpSocket->abort();// Or maybe tcpSocket->close()?
} }
readBufferEnd = readBuffer; readBufferEnd = readBuffer;
writeBufferEnd = writeBuffer; writeBufferEnd = writeBuffer;
wait_for_connection_establishment = false; wait_for_connection_establishment = false;
resetPositions(); interpolatedPosition.reset();
}
//! resets/initializes the array of positions kept for position interpolati
on
void TelescopeTCP::resetPositions()
{
for (position_pointer = positions; position_pointer < end_position;
position_pointer++)
{
position_pointer->server_micros = 0x7FFFFFFFFFFFFFFFLL;
position_pointer->client_micros = 0x7FFFFFFFFFFFFFFFLL;
position_pointer->pos[0] = 0.0;
position_pointer->pos[1] = 0.0;
position_pointer->pos[2] = 0.0;
position_pointer->status = 0;
}
position_pointer = positions;
} }
//! queues a GOTO command with the specified position to the write buffer. //! queues a GOTO command with the specified position to the write buffer.
//! For the data format of the command see the //! For the data format of the command see the
//! "Stellarium telescope control protocol" text file //! "Stellarium telescope control protocol" text file
void TelescopeTCP::telescopeGoto(const Vec3d &j2000Pos) void TelescopeTCP::telescopeGoto(const Vec3d &j2000Pos)
{ {
if (isConnected()) if (!isConnected())
return;
Vec3d position = j2000Pos;
if (equinox == EquinoxJNow)
{ {
if (writeBufferEnd - writeBuffer + 20 < (int)sizeof(writeBuf const StelNavigator* navigator = StelApp::getInstance().getC
fer)) ore()->getNavigator();
{ position = navigator->j2000ToEquinoxEqu(j2000Pos);
const double ra_signed = atan2(j2000Pos[1], j2000Pos }
[0]);
//Workaround for the discrepancy in precision betwee if (writeBufferEnd - writeBuffer + 20 < (int)sizeof(writeBuffer))
n Windows/Linux/PPC Macs and Intel Macs: {
const double ra = (ra_signed >= 0) ? ra_signed : (ra const double ra_signed = atan2(position[1], position[0]);
_signed + 2.0 * M_PI); //Workaround for the discrepancy in precision between Window
const double dec = atan2(j2000Pos[2], sqrt(j2000Pos[ s/Linux/PPC Macs and Intel Macs:
0]*j2000Pos[0]+j2000Pos[1]*j2000Pos[1])); const double ra = (ra_signed >= 0) ? ra_signed : (ra_signed
unsigned int ra_int = (unsigned int)floor(0.5 + ra*( + 2.0 * M_PI);
((unsigned int)0x80000000)/M_PI)); const double dec = atan2(position[2], sqrt(position[0]*posit
int dec_int = (int)floor(0.5 + dec*(((unsigned int)0 ion[0]+position[1]*position[1]));
x80000000)/M_PI)); unsigned int ra_int = (unsigned int)floor(0.5 + ra*(((unsign
// length of packet: ed int)0x80000000)/M_PI));
*writeBufferEnd++ = 20; int dec_int = (int)floor(0.5 + dec*(((unsigned int)0x8000000
*writeBufferEnd++ = 0; 0)/M_PI));
// type of packet: // length of packet:
*writeBufferEnd++ = 0; *writeBufferEnd++ = 20;
*writeBufferEnd++ = 0; *writeBufferEnd++ = 0;
// client_micros: // type of packet:
qint64 now = getNow(); *writeBufferEnd++ = 0;
*writeBufferEnd++ = now; *writeBufferEnd++ = 0;
now>>=8; // client_micros:
*writeBufferEnd++ = now; qint64 now = getNow();
now>>=8; *writeBufferEnd++ = now;
*writeBufferEnd++ = now; now>>=8;
now>>=8; *writeBufferEnd++ = now;
*writeBufferEnd++ = now; now>>=8;
now>>=8; *writeBufferEnd++ = now;
*writeBufferEnd++ = now; now>>=8;
now>>=8; *writeBufferEnd++ = now;
*writeBufferEnd++ = now; now>>=8;
now>>=8; *writeBufferEnd++ = now;
*writeBufferEnd++ = now; now>>=8;
now>>=8; *writeBufferEnd++ = now;
*writeBufferEnd++ = now; now>>=8;
// ra: *writeBufferEnd++ = now;
*writeBufferEnd++ = ra_int; now>>=8;
ra_int>>=8; *writeBufferEnd++ = now;
*writeBufferEnd++ = ra_int; // ra:
ra_int>>=8; *writeBufferEnd++ = ra_int;
*writeBufferEnd++ = ra_int; ra_int>>=8;
ra_int>>=8; *writeBufferEnd++ = ra_int;
*writeBufferEnd++ = ra_int; ra_int>>=8;
// dec: *writeBufferEnd++ = ra_int;
*writeBufferEnd++ = dec_int; ra_int>>=8;
dec_int>>=8; *writeBufferEnd++ = ra_int;
*writeBufferEnd++ = dec_int; // dec:
dec_int>>=8; *writeBufferEnd++ = dec_int;
*writeBufferEnd++ = dec_int; dec_int>>=8;
dec_int>>=8; *writeBufferEnd++ = dec_int;
*writeBufferEnd++ = dec_int; dec_int>>=8;
} *writeBufferEnd++ = dec_int;
else dec_int>>=8;
{ *writeBufferEnd++ = dec_int;
qDebug() << "TelescopeTCP(" << name << ")::telescope }
Goto: "<< "communication is too slow, I will ignore this command"; else
} {
qDebug() << "TelescopeTCP(" << name << ")::telescopeGoto: "<
< "communication is too slow, I will ignore this command";
} }
} }
void TelescopeTCP::performWriting(void) void TelescopeTCP::performWriting(void)
{ {
const int to_write = writeBufferEnd - writeBuffer; const int to_write = writeBufferEnd - writeBuffer;
const int rc = tcpSocket->write(writeBuffer, to_write); const int rc = tcpSocket->write(writeBuffer, to_write);
if (rc < 0) if (rc < 0)
{ {
//TODO: Better error message. See the Qt documentation. //TODO: Better error message. See the Qt documentation.
skipping to change at line 420 skipping to change at line 418
(int)(((unsigned int)(unsign ed char)(p[16])) | (int)(((unsigned int)(unsign ed char)(p[16])) |
(((unsigned int)(unsign ed char)(p[17])) << 8) | (((unsigned int)(unsign ed char)(p[17])) << 8) |
(((unsigned int)(unsign ed char)(p[18])) << 16) | (((unsigned int)(unsign ed char)(p[18])) << 16) |
(((unsigned int)(unsign ed char)(p[19])) << 24)); (((unsigned int)(unsign ed char)(p[19])) << 24));
const int status = const int status =
(int)(((unsigned int)(unsign ed char)(p[20])) | (int)(((unsigned int)(unsign ed char)(p[20])) |
(((unsigned int)(unsign ed char)(p[21])) << 8) | (((unsigned int)(unsign ed char)(p[21])) << 8) |
(((unsigned int)(unsign ed char)(p[22])) << 16) | (((unsigned int)(unsign ed char)(p[22])) << 16) |
(((unsigned int)(unsign ed char)(p[23])) << 24)); (((unsigned int)(unsign ed char)(p[23])) << 24));
// remember the time and received po
sition so that later we
// will know where the telescope is
pointing to:
position_pointer++;
if (position_pointer >= end_position
)
position_pointer = positions
;
position_pointer->server_micros = se
rver_micros;
position_pointer->client_micros = ge
tNow();
const double ra = ra_int * (M_PI/( unsigned int)0x80000000); const double ra = ra_int * (M_PI/( unsigned int)0x80000000);
const double dec = dec_int * (M_PI/( unsigned int)0x80000000); const double dec = dec_int * (M_PI/( unsigned int)0x80000000);
const double cdec = cos(dec); const double cdec = cos(dec);
position_pointer->pos[0] = cos(ra)*c Vec3d position(cos(ra)*cdec, sin(ra)
dec; *cdec, sin(dec));
position_pointer->pos[1] = sin(ra)*c Vec3d j2000Position = position;
dec; if (equinox == EquinoxJNow)
position_pointer->pos[2] = sin(dec); {
position_pointer->status = status; const StelNavigator* navigat
or = StelApp::getInstance().getCore()->getNavigator();
j2000Position = navigator->e
quinoxEquToJ2000(position);
}
interpolatedPosition.add(j2000Positi
on, getNow(), server_micros, status);
} }
break; break;
default: default:
qDebug() << "TelescopeTCP(" << name << ")::performReading: " << "ignoring unknown packet, type: " << type; qDebug() << "TelescopeTCP(" << name << ")::performReading: " << "ignoring unknown packet, type: " << type;
break; break;
} }
p += size; p += size;
} }
if (p >= readBufferEnd) if (p >= readBufferEnd)
{ {
skipping to change at line 460 skipping to change at line 455
memmove(readBuffer, p, readBufferEnd - p); memmove(readBuffer, p, readBufferEnd - p);
readBufferEnd -= (p - readBuffer); readBufferEnd -= (p - readBuffer);
} }
} }
} }
//! estimates where the telescope is by interpolation in the stored //! estimates where the telescope is by interpolation in the stored
//! telescope positions: //! telescope positions:
Vec3d TelescopeTCP::getJ2000EquatorialPos(const StelNavigator*) const Vec3d TelescopeTCP::getJ2000EquatorialPos(const StelNavigator*) const
{ {
if (position_pointer->client_micros == 0x7FFFFFFFFFFFFFFFLL)
{
return Vec3d(0,0,0);
}
const qint64 now = getNow() - time_delay; const qint64 now = getNow() - time_delay;
const Position *p = position_pointer; return interpolatedPosition.get(now);
do
{
const Position *pp = p;
if (pp == positions) pp = end_position;
pp--;
if (pp->client_micros == 0x7FFFFFFFFFFFFFFFLL) break;
if (pp->client_micros <= now && now <= p->client_micros)
{
if (pp->client_micros != p->client_micros)
{
Vec3d rval = p->pos * (now - pp->client_micr
os) + pp->pos * (p->client_micros - now);
double f = rval.lengthSquared();
if (f > 0.0)
{
return (1.0/sqrt(f))*rval;
}
}
break;
}
p = pp;
}
while (p != position_pointer);
return p->pos;
} }
//! checks if the socket is connected, tries to connect if it is not //! checks if the socket is connected, tries to connect if it is not
//@return true if the socket is connected //@return true if the socket is connected
bool TelescopeTCP::prepareCommunication() bool TelescopeTCP::prepareCommunication()
{ {
if(tcpSocket->state() == QAbstractSocket::ConnectedState) if(tcpSocket->state() == QAbstractSocket::ConnectedState)
{ {
if(wait_for_connection_establishment) if(wait_for_connection_establishment)
{ {
 End of changes. 17 change blocks. 
145 lines changed or deleted 105 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/