small cleanup for interface position hooks, updates to support using a provided altitude when sending emane events based on position hooks
This commit is contained in:
parent
102fa410fe
commit
3f17706c28
9 changed files with 76 additions and 61 deletions
|
@ -705,7 +705,6 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
x = request.position.x
|
||||
y = request.position.y
|
||||
options.set_position(x, y)
|
||||
lat, lon, alt = None, None, None
|
||||
has_geo = request.HasField("geo")
|
||||
if has_geo:
|
||||
lat = request.geo.lat
|
||||
|
|
|
@ -369,8 +369,7 @@ class EmaneManager(ModelManager):
|
|||
)
|
||||
emane_node.model.post_startup()
|
||||
for netif in emane_node.netifs():
|
||||
x, y, z = netif.node.position.get()
|
||||
emane_node.setnemposition(netif, x, y, z)
|
||||
netif.setposition()
|
||||
|
||||
def reset(self) -> None:
|
||||
"""
|
||||
|
@ -806,6 +805,7 @@ class EmaneManager(ModelManager):
|
|||
|
||||
# don"t use node.setposition(x,y,z) which generates an event
|
||||
node.position.set(x, y, z)
|
||||
node.position.set_geo(lon, lat, alt)
|
||||
node_data = node.data(message_type=0, lat=lat, lon=lon, alt=alt)
|
||||
self.session.broadcast_node(node_data)
|
||||
return True
|
||||
|
|
|
@ -4,7 +4,7 @@ share the same MAC+PHY model.
|
|||
"""
|
||||
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Type
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Type
|
||||
|
||||
from core.emulator.distributed import DistributedServer
|
||||
from core.emulator.enumerations import LinkTypes, NodeTypes, RegisterTlvs
|
||||
|
@ -172,8 +172,7 @@ class EmaneNet(CoreNetworkBase):
|
|||
# at this point we register location handlers for generating
|
||||
# EMANE location events
|
||||
netif.poshook = self.setnemposition
|
||||
x, y, z = netif.node.position.get()
|
||||
self.setnemposition(netif, x, y, z)
|
||||
netif.setposition()
|
||||
|
||||
def deinstallnetifs(self) -> None:
|
||||
"""
|
||||
|
@ -186,28 +185,45 @@ class EmaneNet(CoreNetworkBase):
|
|||
netif.shutdown()
|
||||
netif.poshook = None
|
||||
|
||||
def setnemposition(
|
||||
self, netif: CoreInterface, x: float, y: float, z: float
|
||||
) -> None:
|
||||
def _nem_position(
|
||||
self, netif: CoreInterface
|
||||
) -> Optional[Tuple[int, float, float, float]]:
|
||||
"""
|
||||
Publish a NEM location change event using the EMANE event service.
|
||||
Creates nem position for emane event for a given interface.
|
||||
|
||||
:param netif: interface to get nem emane position for
|
||||
:return: nem position tuple, None otherwise
|
||||
"""
|
||||
if self.session.emane.service is None:
|
||||
logging.info("position service not available")
|
||||
return
|
||||
nemid = self.getnemid(netif)
|
||||
ifname = netif.localname
|
||||
if nemid is None:
|
||||
logging.info("nemid for %s is unknown", ifname)
|
||||
return
|
||||
node = netif.node
|
||||
x, y, z = node.getposition()
|
||||
lat, lon, alt = self.session.location.getgeo(x, y, z)
|
||||
event = LocationEvent()
|
||||
|
||||
if node.position.alt is not None:
|
||||
alt = node.position.alt
|
||||
# altitude must be an integer or warning is printed
|
||||
# unused: yaw, pitch, roll, azimuth, elevation, velocity
|
||||
alt = int(round(alt))
|
||||
event.append(nemid, latitude=lat, longitude=lon, altitude=alt)
|
||||
self.session.emane.service.publish(0, event)
|
||||
return nemid, lon, lat, alt
|
||||
|
||||
def setnemposition(self, netif: CoreInterface) -> None:
|
||||
"""
|
||||
Publish a NEM location change event using the EMANE event service.
|
||||
|
||||
:param netif: interface to set nem position for
|
||||
"""
|
||||
if self.session.emane.service is None:
|
||||
logging.info("position service not available")
|
||||
return
|
||||
|
||||
position = self._nem_position(netif)
|
||||
if position:
|
||||
nemid, lon, lat, alt = position
|
||||
event = LocationEvent()
|
||||
event.append(nemid, latitude=lat, longitude=lon, altitude=alt)
|
||||
self.session.emane.service.publish(0, event)
|
||||
|
||||
def setnempositions(self, moved_netifs: List[CoreInterface]) -> None:
|
||||
"""
|
||||
|
@ -223,18 +239,9 @@ class EmaneNet(CoreNetworkBase):
|
|||
return
|
||||
|
||||
event = LocationEvent()
|
||||
i = 0
|
||||
for netif in moved_netifs:
|
||||
nemid = self.getnemid(netif)
|
||||
ifname = netif.localname
|
||||
if nemid is None:
|
||||
logging.info("nemid for %s is unknown", ifname)
|
||||
continue
|
||||
x, y, z = netif.node.getposition()
|
||||
lat, lon, alt = self.session.location.getgeo(x, y, z)
|
||||
# altitude must be an integer or warning is printed
|
||||
alt = int(round(alt))
|
||||
event.append(nemid, latitude=lat, longitude=lon, altitude=alt)
|
||||
i += 1
|
||||
|
||||
position = self._nem_position(netif)
|
||||
if position:
|
||||
nemid, lon, lat, alt = position
|
||||
event.append(nemid, latitude=lat, longitude=lon, altitude=alt)
|
||||
self.session.emane.service.publish(0, event)
|
||||
|
|
|
@ -806,6 +806,7 @@ class Session:
|
|||
using_lat_lon_alt = has_empty_position and has_lat_lon_alt
|
||||
if using_lat_lon_alt:
|
||||
x, y, _ = self.location.getxyz(lat, lon, alt)
|
||||
node.position.set_geo(lon, lat, alt)
|
||||
|
||||
# set position and broadcast
|
||||
if None not in [x, y]:
|
||||
|
|
|
@ -370,20 +370,16 @@ class BasicRangeModel(WirelessModel):
|
|||
with self._netifslock:
|
||||
return self._netifs[netif]
|
||||
|
||||
def set_position(
|
||||
self, netif: CoreInterface, x: float = None, y: float = None, z: float = None
|
||||
) -> None:
|
||||
def set_position(self, netif: CoreInterface) -> None:
|
||||
"""
|
||||
A node has moved; given an interface, a new (x,y,z) position has
|
||||
been set; calculate the new distance between other nodes and link or
|
||||
unlink node pairs based on the configured range.
|
||||
|
||||
:param netif: network interface to set position for
|
||||
:param x: x position
|
||||
:param y: y position
|
||||
:param z: z position
|
||||
:return: nothing
|
||||
"""
|
||||
x, y, z = netif.node.position.get()
|
||||
self._netifslock.acquire()
|
||||
self._netifs[netif] = (x, y, z)
|
||||
if x is None or y is None:
|
||||
|
|
|
@ -422,7 +422,7 @@ class CoreNodeBase(NodeBase):
|
|||
changed = super().setposition(x, y, z)
|
||||
if changed:
|
||||
for netif in self.netifs(sort=True):
|
||||
netif.setposition(x, y, z)
|
||||
netif.setposition()
|
||||
|
||||
def commonnets(
|
||||
self, obj: "CoreNodeBase", want_ctrl: bool = False
|
||||
|
@ -1173,11 +1173,13 @@ class Position:
|
|||
:param x: x position
|
||||
:param y: y position
|
||||
:param z: z position
|
||||
:return:
|
||||
"""
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.z = z
|
||||
self.lon = None
|
||||
self.lat = None
|
||||
self.alt = None
|
||||
|
||||
def set(self, x: float = None, y: float = None, z: float = None) -> bool:
|
||||
"""
|
||||
|
@ -1202,3 +1204,24 @@ class Position:
|
|||
:return: x,y,z position tuple
|
||||
"""
|
||||
return self.x, self.y, self.z
|
||||
|
||||
def set_geo(self, lon: float, lat: float, alt: float) -> None:
|
||||
"""
|
||||
Set geo position lon, lat, alt.
|
||||
|
||||
:param lon: longitude value
|
||||
:param lat: latitude value
|
||||
:param alt: altitude value
|
||||
:return: nothing
|
||||
"""
|
||||
self.lon = lon
|
||||
self.lat = lat
|
||||
self.alt = alt
|
||||
|
||||
def get_geo(self) -> Tuple[float, float, float]:
|
||||
"""
|
||||
Retrieve current geo position lon, lat, alt.
|
||||
|
||||
:return: lon, lat, alt position tuple
|
||||
"""
|
||||
return self.lon, self.lat, self.alt
|
||||
|
|
|
@ -50,7 +50,7 @@ class CoreInterface:
|
|||
self.addrlist = []
|
||||
self.hwaddr = None
|
||||
# placeholder position hook
|
||||
self.poshook = lambda a, b, c, d: None
|
||||
self.poshook = lambda x: None
|
||||
# used with EMANE
|
||||
self.transport_type = None
|
||||
# node interface index
|
||||
|
@ -209,16 +209,14 @@ class CoreInterface:
|
|||
self._params = getattr(self, name)
|
||||
setattr(self, name, tmp)
|
||||
|
||||
def setposition(self, x: float, y: float, z: float) -> None:
|
||||
def setposition(self) -> None:
|
||||
"""
|
||||
Dispatch position hook handler.
|
||||
Dispatch position hook handler when possible.
|
||||
|
||||
:param x: x position
|
||||
:param y: y position
|
||||
:param z: z position
|
||||
:return: nothing
|
||||
"""
|
||||
self.poshook(self, x, y, z)
|
||||
if self.poshook and self.node:
|
||||
self.poshook(self)
|
||||
|
||||
def __lt__(self, other: "CoreInterface") -> bool:
|
||||
"""
|
||||
|
|
|
@ -1079,11 +1079,7 @@ class WlanNode(CoreNetwork):
|
|||
super().attach(netif)
|
||||
if self.model:
|
||||
netif.poshook = self.model.position_callback
|
||||
if netif.node is None:
|
||||
return
|
||||
x, y, z = netif.node.position.get()
|
||||
# invokes any netif.poshook
|
||||
netif.setposition(x, y, z)
|
||||
netif.setposition()
|
||||
|
||||
def setmodel(self, model: "WirelessModelType", config: Dict[str, str]):
|
||||
"""
|
||||
|
@ -1098,9 +1094,7 @@ class WlanNode(CoreNetwork):
|
|||
self.model = model(session=self.session, _id=self.id)
|
||||
for netif in self.netifs():
|
||||
netif.poshook = self.model.position_callback
|
||||
if netif.poshook and netif.node:
|
||||
x, y, z = netif.node.position.get()
|
||||
netif.poshook(netif, x, y, z)
|
||||
netif.setposition()
|
||||
self.updatemodel(config)
|
||||
elif model.config_type == RegisterTlvs.MOBILITY.value:
|
||||
self.mobility = model(session=self.session, _id=self.id)
|
||||
|
@ -1119,9 +1113,7 @@ class WlanNode(CoreNetwork):
|
|||
)
|
||||
self.model.update_config(config)
|
||||
for netif in self.netifs():
|
||||
if netif.poshook and netif.node:
|
||||
x, y, z = netif.node.position.get()
|
||||
netif.poshook(netif, x, y, z)
|
||||
netif.setposition()
|
||||
|
||||
def all_link_data(self, flags: int) -> List[LinkData]:
|
||||
"""
|
||||
|
|
|
@ -517,7 +517,7 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
|||
if self.old_up:
|
||||
self.net_client.device_up(self.localname)
|
||||
|
||||
def setposition(self, x: float = None, y: float = None, z: float = None) -> bool:
|
||||
def setposition(self, x: float = None, y: float = None, z: float = None) -> None:
|
||||
"""
|
||||
Uses setposition from both parent classes.
|
||||
|
||||
|
@ -526,9 +526,8 @@ class Rj45Node(CoreNodeBase, CoreInterface):
|
|||
:param z: z position
|
||||
:return: True if position changed, False otherwise
|
||||
"""
|
||||
result = CoreNodeBase.setposition(self, x, y, z)
|
||||
CoreInterface.setposition(self, x, y, z)
|
||||
return result
|
||||
CoreNodeBase.setposition(self, x, y, z)
|
||||
CoreInterface.setposition(self)
|
||||
|
||||
def termcmdstring(self, sh: str) -> str:
|
||||
"""
|
||||
|
|
Loading…
Reference in a new issue