EMANE  1.2.1
positionutils.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 - Adjacent Link LLC, Bridgewater, New Jersey
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * * Neither the name of Adjacent Link LLC nor the names of its
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #ifndef EMANEPHYPOSITIONUTILS_HEADER_
34 #define EMANEPHYPOSITIONUTILS_HEADER_
35 
36 #include "locationinfo.h"
37 #include "positionneu.h"
38 
40 
41 #include <tuple>
42 
43 namespace EMANE
44 {
45  namespace Utils
46  {
47  inline
48  std::tuple<double,double,double>
50  const PositionNEU & localAntennaPositionNEU,
51  const PositionOrientationVelocity & remoteLocationInfo,
52  const PositionNEU & remoteAntennaPositionNEU)
53  {
54  // remote placement
55  //PositionNEU remoteAntennaPositionNEU{remoteAntennaPositionNEU};
56 
57  // NEU for the remote node, includes rotation for orientation
58  PositionNEU remoteNEU{localLocationInfo.getPositionNEU(remoteLocationInfo)};
59 
60  PositionNEU mutableRemoteAntennaPositionNEU{remoteAntennaPositionNEU};
61 
62  const auto & localOrientation = localLocationInfo.getAdjustedOrientation().first;
63  const auto & remoteOrientation = remoteLocationInfo.getAdjustedOrientation().first;
64 
65  // rotate the remote antenna position based on local and remote orientation
66  mutableRemoteAntennaPositionNEU.rotate(localOrientation.getYawRadians() - remoteOrientation.getYawRadians(),
67  localOrientation.getPitchRadians() - remoteOrientation.getPitchRadians(),
68  localOrientation.getRollRadians() - remoteOrientation.getRollRadians());
69 
70  // adjust the remote NEM to include antenna placement - accounts for both local and remote platform
71 
72  // Update NEU to include antenna location on the platform. This accounts for both local and remote platforms.
73  remoteNEU.adjust(-localAntennaPositionNEU.getNorthMeters() + mutableRemoteAntennaPositionNEU.getNorthMeters(),
74  -localAntennaPositionNEU.getEastMeters() + mutableRemoteAntennaPositionNEU.getEastMeters(),
75  -localAntennaPositionNEU.getUpMeters() + mutableRemoteAntennaPositionNEU.getUpMeters());
76 
77  // get distance
78  double dDistanceMeters{NORMALIZE_VECTOR(remoteNEU.getNorthMeters(), remoteNEU.getEastMeters(), remoteNEU.getUpMeters())};
79 
80  // get elevation
81  double dElevationDegrees{asin(remoteNEU.getUpMeters() / dDistanceMeters) * (180.0 / M_PI)};
82 
83  // get azimuth
84  double dAzimuthDegrees{};
85 
86  if(remoteNEU.getNorthMeters() == 0.0)
87  {
88  if( remoteNEU.getEastMeters() > 0.0)
89  {
90  dAzimuthDegrees = 90.0;
91  }
92  else
93  {
94  dAzimuthDegrees = 270.0;
95  }
96  }
97  else
98  {
99  if(remoteNEU.getEastMeters() == 0.0)
100  {
101  if(remoteNEU.getNorthMeters() > 0.0)
102  {
103  dAzimuthDegrees = 0.0;
104  }
105  else
106  {
107  dAzimuthDegrees = 180.0;
108  }
109  }
110  else
111  {
112  dAzimuthDegrees = atan(remoteNEU.getEastMeters() / remoteNEU.getNorthMeters()) * (180.0 / M_PIl);
113  }
114 
115  if(remoteNEU.getNorthMeters() < 0.0)
116  {
117  dAzimuthDegrees += 180.0;
118  }
119 
120  if((remoteNEU.getNorthMeters() > 0.0) && ( remoteNEU.getEastMeters() < 0.0))
121  {
122  dAzimuthDegrees += 360.0;
123  }
124  }
125 
126  return std::make_tuple(dAzimuthDegrees, dElevationDegrees, dDistanceMeters);
127  }
128 
129  inline std::pair<double,double>
130  calculateLookupAngles(double dAzReference,
131  double dAzPointing,
132  double dElReference,
133  double dElPointing)
134  {
135  // Az = Az(reference) - Az(pointing)
136  double dAzimuth {dAzReference - dAzPointing};
137 
138  // El = El(reference) - El(pointing)
139  double dElevation = {dElReference - dElPointing};
140 
141  // ensure (0.0 <= Az < 360.0)
142  Utils::AI_TO_BE_DEGREES(dAzimuth, 0.0, 360.0);
143 
144  // ensure (0.0 <= El < 360.0)
145  Utils::AI_TO_BE_DEGREES(dElevation, 0.0, 360.0);
146 
147  // ensure (-90 <= El <= 90)
149 
150  return {dAzimuth, dElevation};
151  }
152 
153  inline bool
154  checkHorizon(const double dHeightMeters1,
155  const double dHeightMeters2,
156  const double dDistanceMeters)
157  {
158  const double dDH1{3570.0 * sqrt(dHeightMeters1 < 0.0 ? 0.0 : dHeightMeters1)};
159 
160  const double dDH2{3570.0 * sqrt(dHeightMeters2 < 0.0 ? 0.0 : dHeightMeters2)};
161 
162  return (dDH1 + dDH2) > dDistanceMeters;
163  }
164  }
165 }
166 
167 #endif // EMANEPHYPOSITIONUTILS_HEADER_
168 
std::tuple< double, double, double > calculateDirection(const PositionOrientationVelocity &localLocationInfo, const PositionNEU &localAntennaPositionNEU, const PositionOrientationVelocity &remoteLocationInfo, const PositionNEU &remoteAntennaPositionNEU)
Definition: positionutils.h:49
std::pair< const Orientation &, bool > getAdjustedOrientation() const
double getNorthMeters() const
Definition: positionneu.inl:48
std::pair< double, double > calculateLookupAngles(double dAzReference, double dAzPointing, double dElReference, double dElPointing)
void AI_TO_BE_DEGREES(double &val, const double A, const double B)
void NEG_90_TO_POS_90_DEGREES(double &val)
double NORMALIZE_VECTOR(const double x, const double y, const double z)
double getUpMeters() const
Definition: positionneu.inl:60
bool checkHorizon(const double dHeightMeters1, const double dHeightMeters2, const double dDistanceMeters)
PositionNEU getPositionNEU(const PositionOrientationVelocity &other) const
Definition: agent.h:43
double getEastMeters() const
Definition: positionneu.inl:54