vdr  2.2.0
positioner.c
Go to the documentation of this file.
1 /*
2  * positioner.c: Steerable dish positioning
3  *
4  * See the main source file 'vdr.c' for copyright information and
5  * how to reach the author.
6  *
7  * For an explanation (in German) of the theory behind the calculations see
8  * http://www.vdr-portal.de/board17-developer/board97-vdr-core/p1154305-grundlagen-und-winkelberechnungen-f%C3%BCr-h-h-diseqc-motor-antennenanlagen
9  * by Albert Danis.
10  *
11  * $Id: positioner.c 3.5 2015/02/14 11:54:31 kls Exp $
12  */
13 
14 #include "positioner.h"
15 #include <math.h>
16 #include "config.h"
17 
18 #define SAT_EARTH_RATIO 0.1513 // the Earth's radius, divided by the distance from the Earth's center to the satellite
19 #define SAT_VISIBILITY_LAT 812 // the absolute latitude beyond which no satellite can be seen (degrees * 10)
20 
21 #define RAD(x) ((x) * M_PI / 1800)
22 #define DEG(x) ((x) * 1800 / M_PI)
23 
25 
27 {
29  frontend = -1;
32  swingTime = 0;
33  delete positioner;
34  positioner = this;
35 }
36 
38 {
39  positioner = NULL;
40 }
41 
43 {
44  while (Angle < -1800)
45  Angle += 3600;
46  while (Angle > 1800)
47  Angle -= 3600;
48  return Angle;
49 }
50 
51 int cPositioner::CalcHourAngle(int Longitude)
52 {
53  double Alpha = RAD(Longitude - Setup.SiteLon);
54  double Lat = RAD(Setup.SiteLat);
55  int Sign = Setup.SiteLat >= 0 ? -1 : 1; // angles to the right are positive, angles to the left are negative
56  return Sign * round(DEG(atan2(sin(Alpha), cos(Alpha) - cos(Lat) * SAT_EARTH_RATIO)));
57 }
58 
59 int cPositioner::CalcLongitude(int HourAngle)
60 {
61  double Lat = RAD(Setup.SiteLat);
62  double Lon = RAD(Setup.SiteLon);
63  double Delta = RAD(HourAngle);
64  double Alpha = Delta - asin(sin(M_PI - Delta) * cos(Lat) * SAT_EARTH_RATIO);
65  int Sign = Setup.SiteLat >= 0 ? 1 : -1;
66  return NormalizeAngle(round(DEG(Lon - Sign * Alpha)));
67 }
68 
70 {
71  double Delta;
72  if (abs(Setup.SiteLat) <= SAT_VISIBILITY_LAT)
73  Delta = acos(SAT_EARTH_RATIO / cos(RAD(Setup.SiteLat)));
74  else
75  Delta = 0;
76  if ((Setup.SiteLat >= 0) != (Direction == pdLeft))
77  Delta = -Delta;
78  return NormalizeAngle(round(DEG(RAD(Setup.SiteLon) + Delta)));
79 }
80 
82 {
84 }
85 
87 {
88  if (Setup.PositionerSpeed <= 0)
89  return;
90  cMutexLock MutexLock(&mutex);
91  lastLongitude = CurrentLongitude(); // in case the dish was already in motion
92  targetLongitude = Longitude;
95  swingTime = abs(targetHourAngle - lastHourAngle) * 1000 / Setup.PositionerSpeed; // time (ms) it takes to move the dish from lastHourAngle to targetHourAngle
98 }
99 
100 void cPositioner::GotoPosition(uint Number, int Longitude)
101 {
102  if (Longitude != targetLongitude)
103  dsyslog("moving positioner to position %d, longitude %d", Number, Longitude);
104  StartMovementTimer(Longitude);
105 }
106 
107 void cPositioner::GotoAngle(int Longitude)
108 {
109  if (Longitude != targetLongitude)
110  dsyslog("moving positioner to longitude %d", Longitude);
111  StartMovementTimer(Longitude);
112 }
113 
115 {
116  cMutexLock MutexLock(&mutex);
118  int Elapsed = movementStart.Elapsed(); // it's important to make this 'int', otherwise the expression below yields funny results
119  if (swingTime <= Elapsed)
121  else
123  }
124  return lastLongitude;
125 }
126 
127 bool cPositioner::IsMoving(void) const
128 {
129  cMutexLock MutexLock(&mutex);
130  return CurrentLongitude() != targetLongitude;
131 }
132 
134 {
135  return positioner;
136 }
137 
139 {
140  delete positioner;
141 }
static int CalcHourAngle(int Longitude)
Takes the longitude and latitude of the dish location from the system setup and the given Longitude t...
Definition: positioner.c:51
#define RAD(x)
Definition: positioner.c:21
#define dsyslog(a...)
Definition: tools.h:36
void Set(int Ms=0)
Definition: tools.c:738
static int NormalizeAngle(int Angle)
Normalizes the given Angle into the range -1800...1800.
Definition: positioner.c:42
int swingTime
Definition: positioner.h:41
virtual void GotoPosition(uint Number, int Longitude)
Move the dish to the satellite position stored under the given Number.
Definition: positioner.c:100
int targetLongitude
Definition: positioner.h:38
static cPositioner * positioner
Definition: positioner.h:34
int targetHourAngle
Definition: positioner.h:40
static cPositioner * GetPositioner(void)
Returns a previously created positioner.
Definition: positioner.c:133
A steerable satellite dish generally points to the south on the northern hemisphere, and to the north on the southern hemisphere (unless you're located directly on the equator, in which case the general direction is "up").
Definition: positioner.h:31
virtual void GotoAngle(int Longitude)
Move the dish to the given angular position.
Definition: positioner.c:107
ePositionerDirection
Definition: positioner.h:83
int PositionerSwing
Definition: config.h:279
virtual bool IsMoving(void) const
Returns true if the dish is currently moving as a result of a call to GotoPosition() or GotoAngle()...
Definition: positioner.c:127
cSetup Setup
Definition: config.c:372
int SiteLon
Definition: config.h:277
int PositionerLastLon
Definition: config.h:280
virtual int CurrentLongitude(void) const
Returns the longitude the dish currently points to.
Definition: positioner.c:114
virtual ~cPositioner()
Definition: positioner.c:37
int frontend
Definition: positioner.h:36
int capabilities
Definition: positioner.h:35
cMutex mutex
Definition: positioner.h:33
static int CalcLongitude(int HourAngle)
Returns the longitude of the satellite position the dish points at when the positioner is moved to th...
Definition: positioner.c:59
void StartMovementTimer(int Longitude)
Starts a timer that estimates how long it will take to move the dish from the current position to the...
Definition: positioner.c:86
cTimeMs movementStart
Definition: positioner.h:42
int PositionerSpeed
Definition: config.h:278
#define DEG(x)
Definition: positioner.c:22
static int HorizonLongitude(ePositionerDirection Direction)
Returns the longitude of the satellite position that is just at the horizon when looking in the given...
Definition: positioner.c:69
int lastLongitude
Definition: positioner.h:37
#define SAT_EARTH_RATIO
Definition: positioner.c:18
int HardLimitLongitude(ePositionerDirection Direction) const
Returns the longitude of the positioner's hard limit in the given Direction.
Definition: positioner.c:81
int SiteLat
Definition: config.h:276
#define SAT_VISIBILITY_LAT
Definition: positioner.c:19
static void DestroyPositioner(void)
Destroys a previously created positioner.
Definition: positioner.c:138
uint64_t Elapsed(void) const
Definition: tools.c:748
int lastHourAngle
Definition: positioner.h:39
cPositioner(void)
Definition: positioner.c:26