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&#39;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:373
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&#39;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