EMANE  1.2.1
emane/events/locationevent.py
Go to the documentation of this file.
1 #
2 # Copyright (c) 2013-2014,2017 - Adjacent Link LLC, Bridgewater,
3 # New Jersey
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # * Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # * Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in
14 # the documentation and/or other materials provided with the
15 # distribution.
16 # * Neither the name of Adjacent Link LLC nor the names of its
17 # contributors may be used to endorse or promote products derived
18 # from this software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 # POSSIBILITY OF SUCH DAMAGE.
32 #
33 
34 from . import Event
35 from . import locationevent_pb2
36 
37 class LocationEvent(Event):
38  IDENTIFIER = 100
39 
40  def __init__(self):
41  self._event = locationevent_pb2.LocationEvent()
42 
43  def append(self,nemId,**kwargs):
44  hasLatitude = False
45  hasLongitude = False
46  hasAltitude = False
47 
48  hasAzimuth = False
49  hasElevation = False
50  hasMagnitude = False
51 
52  hasRoll = False
53  hasPitch = False
54  hasYaw = False
55 
56  location = self._event.locations.add()
57 
58  location.nemId = nemId
59 
60 
61  for (name,value) in list(kwargs.items()):
62 
63  if name == 'latitude':
64  if isinstance(value,int) or \
65  isinstance(value,float):
66  hasLatitude = True
67  location.position.latitudeDegrees = value
68  else:
69  raise ValueError("latitude must be numeric")
70 
71  elif name == 'longitude':
72  if isinstance(value,int) or \
73  isinstance(value,float):
74  hasLongitude = True
75  location.position.longitudeDegrees = value
76  else:
77  raise ValueError("longitude must be numeric")
78 
79  elif name == 'altitude':
80  if isinstance(value,int) or \
81  isinstance(value,float):
82  hasAltitude = True
83  location.position.altitudeMeters = value
84  else:
85  raise ValueError("altitude must be numeric")
86 
87  elif name == 'azimuth':
88  if isinstance(value,int) or \
89  isinstance(value,float):
90  hasAzimuth = True
91  location.velocity.azimuthDegrees = value
92  else:
93  raise ValueError("azimuth must be numeric")
94 
95  elif name == 'elevation':
96  if isinstance(value,int) or \
97  isinstance(value,float):
98  hasElevation = True
99  location.velocity.elevationDegrees = value
100  else:
101  raise ValueError("elevation must be numeric")
102 
103  elif name == 'magnitude':
104  if isinstance(value,int) or \
105  isinstance(value,float):
106  hasMagnitude = True
107  location.velocity.magnitudeMetersPerSecond = value
108  else:
109  raise ValueError("magnitude must be numeric")
110 
111  elif name == 'roll':
112  if isinstance(value,int) or \
113  isinstance(value,float):
114  hasRoll = True
115  location.orientation.rollDegrees = value
116  else:
117  raise ValueError("roll must be numeric")
118 
119  elif name == 'pitch':
120  if isinstance(value,int) or \
121  isinstance(value,float):
122  hasPitch = True
123  location.orientation.pitchDegrees = value
124  else:
125  raise ValueError("pitch must be numeric")
126 
127  elif name == 'yaw':
128  if isinstance(value,int) or \
129  isinstance(value,float):
130  hasYaw = True
131  location.orientation.yawDegrees = value
132  else:
133  raise ValueError("yaw must be numeric")
134 
135  else:
136  raise KeyError("unknown parameter: %s" % name)
137 
138  if not (hasLatitude and hasLongitude and hasAltitude):
139  raise KeyError("must specify latitude, longitude and altitude")
140 
141  if (hasAzimuth and not (hasElevation and hasMagnitude)) or \
142  (hasElevation and not (hasAzimuth and hasMagnitude)) or \
143  (hasMagnitude and not (hasAzimuth and hasElevation)):
144  raise KeyError("must specify azimuth, elevation and magnitude when specifing velocity")
145 
146  if (hasRoll and not (hasPitch and hasYaw)) or \
147  (hasPitch and not (hasRoll and hasYaw)) or \
148  (hasYaw and not (hasRoll and hasPitch)):
149  raise KeyError("must specify roll, pitch and yaw when specifing orientation")
150 
151  def serialize(self):
152  return self._event.SerializeToString()
153 
154  def restore(self,data):
155  self._event.ParseFromString(data)
156 
157  def __iter__(self):
158  for location in self._event.locations:
159  kwargs = {'latitude':location.position.latitudeDegrees,
160  'longitude' : location.position.longitudeDegrees,
161  'altitude' : location.position.altitudeMeters}
162 
163  if location.HasField('velocity'):
164  kwargs['azimuth'] = location.velocity.azimuthDegrees
165  kwargs['elevation'] = location.velocity.elevationDegrees
166  kwargs['magnitude'] = location.velocity.magnitudeMetersPerSecond
167 
168  if location.HasField('orientation'):
169  kwargs['roll'] = location.orientation.rollDegrees
170  kwargs['pitch'] = location.orientation.pitchDegrees
171  kwargs['yaw'] = location.orientation.yawDegrees
172 
173 
174  yield (location.nemId,kwargs)