vdr 2.7.4
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
36
41
43{
44 while (Angle < -1800)
45 Angle += 3600;
46 while (Angle > 1800)
47 Angle -= 3600;
48 return Angle;
49}
50
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
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{
83 return CalcLongitude(Direction == pdLeft ? -Setup.PositionerSwing : Setup.PositionerSwing);
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
96 movementStart.Set();
97 Setup.PositionerLastLon = targetLongitude;
98}
99
100void 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
107void 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
127bool cPositioner::IsMoving(void) const
128{
129 cMutexLock MutexLock(&mutex);
131}
132
137
139{
140 delete positioner;
141}
A steerable satellite dish generally points to the south on the northern hemisphere,...
Definition positioner.h:31
static cPositioner * GetPositioner(void)
Returns a previously created positioner.
Definition positioner.c:133
static cPositioner * positioner
Definition positioner.h:34
static void DestroyPositioner(void)
Destroys a previously created positioner.
Definition positioner.c:138
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
static int NormalizeAngle(int Angle)
Normalizes the given Angle into the range -1800...1800.
Definition positioner.c:42
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
cMutex mutex
Definition positioner.h:33
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
cTimeMs movementStart
Definition positioner.h:42
int targetLongitude
Definition positioner.h:38
virtual int CurrentLongitude(void) const
Returns the longitude the dish currently points to.
Definition positioner.c:114
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
int lastLongitude
Definition positioner.h:37
virtual ~cPositioner()
Definition positioner.c:37
virtual void GotoPosition(uint Number, int Longitude)
Move the dish to the satellite position stored under the given Number.
Definition positioner.c:100
int lastHourAngle
Definition positioner.h:39
int HardLimitLongitude(ePositionerDirection Direction) const
Returns the longitude of the positioner's hard limit in the given Direction.
Definition positioner.c:81
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 capabilities
Definition positioner.h:35
virtual void GotoAngle(int Longitude)
Move the dish to the given angular position.
Definition positioner.c:107
int targetHourAngle
Definition positioner.h:40
cPositioner(void)
Definition positioner.c:26
cSetup Setup
Definition config.c:372
#define SAT_VISIBILITY_LAT
Definition positioner.c:19
#define SAT_EARTH_RATIO
Definition positioner.c:18
#define RAD(x)
Definition positioner.c:21
#define DEG(x)
Definition positioner.c:22
#define dsyslog(a...)
Definition tools.h:37