Kstars

rotatorutils.cpp
1/*
2 SPDX-FileCopyrightText: 2022 Toni Schriber
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7/******************************************************************************************************
8* Angle calculations are based on position measurements of
9* - Rotator angle in "Circular Angle (A)" mode (0 <> 359.99° CCW)
10* - Camera offset angle & Camera position angle in "Position Angle (PA)" mode (180 <> -179.99° CCW)
11* This leads to the following calculations:
12* - Camera PA = calcCameraAngel(Rotator A)
13* - Rotator A = calcRotatorAngle(Camera PA)
14* - Camera offset PA = calcOffsetAngle(Rotator A, Camera PA)
15*******************************************************************************************************/
16
17#include "rotatorutils.h"
18#include "Options.h"
19
20#include "opticaltrainmanager.h"
21
22#include <indicom.h>
23#include <basedevice.h>
24#include <cmath>
25
26RotatorUtils * RotatorUtils::m_Instance = nullptr;
27
28RotatorUtils * RotatorUtils::Instance()
29{
30 if (m_Instance)
31 return m_Instance;
32
33 m_Instance = new RotatorUtils();
34 return m_Instance;
35}
36
37void RotatorUtils::release()
38{
39 delete (m_Instance);
40 m_Instance = nullptr;
41}
42
43RotatorUtils::RotatorUtils() {}
44
45RotatorUtils::~RotatorUtils() {}
46
47void RotatorUtils::initRotatorUtils(const QString &train)
48{
49 m_Offset = Options::pAOffset();
50 m_Mount = Ekos::OpticalTrainManager::Instance()->getMount(train);
51
52 if (m_Mount)
53 {
54 connect(m_Mount, &ISD::Mount::pierSideChanged, this, [this] (ISD::Mount::PierSide Side)
55 {
56 m_flippedMount = (Side != m_CalPierside);
57 emit changedPierside(Side);
58 });
59 }
60}
61
62double RotatorUtils::calcRotatorAngle(double PositionAngle)
63{
64 if (m_flippedMount)
65 {
66 PositionAngle += 180;
67 }
68 return KSUtils::range360(PositionAngle - m_Offset);
69}
70
71double RotatorUtils::calcCameraAngle(double RotatorAngle, bool flippedImage)
72{
73 double PositionAngle = 0;
74 if (RotatorAngle > 180)
75 {
76 PositionAngle = (RotatorAngle - 360) + m_Offset;
77 }
78 else
79 {
80 PositionAngle = RotatorAngle + m_Offset;
81 }
82 if (!m_flippedMount != !flippedImage) // XOR
83 {
84 if (PositionAngle > 0)
85 {
86 PositionAngle -= 180;
87 }
88 else
89 {
90 PositionAngle += 180;
91 }
92
93 }
94 return KSUtils::rangePA(PositionAngle);
95}
96
97double RotatorUtils::calcOffsetAngle(double RotatorAngle, double PositionAngle)
98{
99 double OffsetAngle = 0;
100 if (RotatorAngle > 180)
101 {
102 OffsetAngle = PositionAngle - (RotatorAngle - 360);
103 }
104 else
105 {
106 OffsetAngle = PositionAngle - RotatorAngle;
107 }
108 if (m_flippedMount)
109 {
110 OffsetAngle -= 180;
111 }
112 return KSUtils::rangePA(OffsetAngle);
113}
114
115void RotatorUtils::updateOffset(double Angle)
116{
117 m_Offset = Angle;
118 Options::setPAOffset(Angle);
119}
120
121ISD::Mount::PierSide RotatorUtils::getMountPierside()
122{
123 return(m_Mount->pierSide());
124}
125
126void RotatorUtils::setImagePierside(ISD::Mount::PierSide ImgPierside)
127{
128 m_ImgPierside = ImgPierside;
129}
130
131bool RotatorUtils::checkImageFlip()
132{
133 bool flipped = false;
134
135 if (m_ImgPierside != ISD::Mount::PIER_UNKNOWN)
136 if (!m_flippedMount != (m_ImgPierside == m_CalPierside)) // XOR
137 flipped = true;
138 return flipped;
139}
140
141double RotatorUtils::DiffPA(double diff)
142{
143 if (diff > 180)
144 return (360 - diff);
145 else
146 return diff;
147}
148
149void RotatorUtils::initTimeFrame(const double EndAngle)
150{
151 m_EndAngle = EndAngle;
152 m_initParameter = true;
153 m_CCW = true;
154}
155
156int RotatorUtils::calcTimeFrame(const double CurrentAngle)
157{
158 m_CurrentTime = QTime::currentTime();
159 m_DeltaTime = m_StartTime.secsTo(m_CurrentTime);
160 m_TimeFrame = 0;
161 if (m_DeltaTime >= 1)
162 {
163 if (m_initParameter)
164 {
165 m_DeltaAngle = CurrentAngle + m_ShiftAngle;
166 // Moving CCW or positive
167 if (m_DeltaAngle >= 360)
168 {
169 if (m_DiffAngle < 0)
170 m_DiffAngle = (360 + m_DiffAngle);
171 }
172 else // Moving CW or negative
173 {
174 if (m_DiffAngle > 0)
175 m_DiffAngle = (360 - m_DiffAngle);
176 m_CCW = false;
177 }
178 m_initParameter = false;
179 }
180 m_DeltaAngle = KSUtils::range360(CurrentAngle + m_ShiftAngle);
181 if (!m_CCW)
182 m_DeltaAngle = 360 - m_DeltaAngle;
183
184 m_TimeFrame = fabs(m_DiffAngle) / fabs(m_DeltaAngle/m_DeltaTime);
185 }
186 return m_TimeFrame;
187}
188
189void RotatorUtils::startTimeFrame(const double StartAngle)
190{
191 m_StartAngle = StartAngle;
192 m_StartTime = QTime::currentTime();
193 m_ShiftAngle = 360 - m_StartAngle;
194 m_DiffAngle = m_EndAngle - m_StartAngle;
195}
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QTime currentTime()
int secsTo(QTime t) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 3 2024 11:49:50 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.