vdr  2.4.1
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 4.0 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 }
cPositioner::DestroyPositioner
static void DestroyPositioner(void)
Destroys a previously created positioner.
Definition: positioner.c:138
SAT_VISIBILITY_LAT
#define SAT_VISIBILITY_LAT
Definition: positioner.c:19
cPositioner::cPositioner
cPositioner(void)
Definition: positioner.c:26
RAD
#define RAD(x)
Definition: positioner.c:21
cSetup::SiteLat
int SiteLat
Definition: config.h:275
cPositioner::NormalizeAngle
static int NormalizeAngle(int Angle)
Normalizes the given Angle into the range -1800...1800.
Definition: positioner.c:42
cPositioner::targetLongitude
int targetLongitude
Definition: positioner.h:38
cPositioner::pcCanNothing
@ pcCanNothing
Definition: positioner.h:71
cPositioner::HardLimitLongitude
int HardLimitLongitude(ePositionerDirection Direction) const
Returns the longitude of the positioner's hard limit in the given Direction.
Definition: positioner.c:81
cPositioner::GotoPosition
virtual void GotoPosition(uint Number, int Longitude)
Move the dish to the satellite position stored under the given Number.
Definition: positioner.c:100
cPositioner::CurrentLongitude
virtual int CurrentLongitude(void) const
Returns the longitude the dish currently points to.
Definition: positioner.c:114
cPositioner::positioner
static cPositioner * positioner
Definition: positioner.h:34
cPositioner::swingTime
int swingTime
Definition: positioner.h:41
cMutexLock
Definition: thread.h:141
Setup
cSetup Setup
Definition: config.c:372
cSetup::PositionerSpeed
int PositionerSpeed
Definition: config.h:277
cPositioner::GetPositioner
static cPositioner * GetPositioner(void)
Returns a previously created positioner.
Definition: positioner.c:133
cTimeMs::Set
void Set(int Ms=0)
Definition: tools.c:774
cSetup::PositionerLastLon
int PositionerLastLon
Definition: config.h:279
cPositioner::IsMoving
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
cPositioner::ePositionerDirection
ePositionerDirection
Definition: positioner.h:83
cSetup::SiteLon
int SiteLon
Definition: config.h:276
cPositioner::pdLeft
@ pdLeft
Definition: positioner.h:83
cPositioner
A steerable satellite dish generally points to the south on the northern hemisphere,...
Definition: positioner.h:31
cPositioner::targetHourAngle
int targetHourAngle
Definition: positioner.h:40
cPositioner::GotoAngle
virtual void GotoAngle(int Longitude)
Move the dish to the given angular position.
Definition: positioner.c:107
dsyslog
#define dsyslog(a...)
Definition: tools.h:37
positioner.h
SAT_EARTH_RATIO
#define SAT_EARTH_RATIO
Definition: positioner.c:18
cPositioner::frontend
int frontend
Definition: positioner.h:36
cPositioner::lastLongitude
int lastLongitude
Definition: positioner.h:37
cPositioner::~cPositioner
virtual ~cPositioner()
Definition: positioner.c:37
cPositioner::HorizonLongitude
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
config.h
cPositioner::mutex
cMutex mutex
Definition: positioner.h:33
cPositioner::capabilities
int capabilities
Definition: positioner.h:35
cPositioner::lastHourAngle
int lastHourAngle
Definition: positioner.h:39
cPositioner::CalcLongitude
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
cPositioner::movementStart
cTimeMs movementStart
Definition: positioner.h:42
cPositioner::StartMovementTimer
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
DEG
#define DEG(x)
Definition: positioner.c:22
cPositioner::CalcHourAngle
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::Elapsed
uint64_t Elapsed(void) const
Definition: tools.c:784
cSetup::PositionerSwing
int PositionerSwing
Definition: config.h:278