Skip to content

Commit

Permalink
[mock_uss/riddp] Enforce min cluster size and fix obfuscation for NET…
Browse files Browse the repository at this point in the history
…0490 (#122)

* [mock_uss/riddp] Enforce min cluster size for NET0940

* add missing function

* make flow more explicit and readable

* apply both extends

* invert order offset-buffer; clarify flow

* add back missing condition

* fix randomization

* clarify implementation of cluster extensions

* add forgotten property decorator
  • Loading branch information
mickmis authored Jul 7, 2023
1 parent 3e86aa2 commit 9083360
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 18 deletions.
68 changes: 50 additions & 18 deletions monitoring/mock_uss/riddp/clustering.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,58 @@ def randomize(self):
v_min = min(p.y for p in self.points)
u_max = max(p.x for p in self.points)
v_max = max(p.y for p in self.points)
return Cluster(
x_min=self.x_min + (u_min - self.x_min) * random.random(),
y_min=self.y_min + (v_min - self.y_min) * random.random(),
x_max=u_max + (self.x_max - u_max) * random.random(),
y_max=v_max + (self.y_max - v_max) * random.random(),
points=self.points,
)

def extend_size(self, min_area_size: float):
scale = math.sqrt(min_area_size / self.area()) / 2
x_offset = random.uniform(-u_max, u_min)
y_offset = random.uniform(-v_max, v_min)
return Cluster(
x_min=self.x_min - scale * self.width(),
x_max=self.x_max + scale * self.width(),
y_min=self.y_min - scale * self.height(),
y_max=self.y_max + scale * self.height(),
x_min=self.x_min + x_offset,
y_min=self.y_min + y_offset,
x_max=self.x_max + x_offset,
y_max=self.y_max + y_offset,
points=self.points,
)

def extend(self, rid_version: RIDVersion, view_area_sqm: float):
"""Extend cluster size and dimensions to the minimum required"""

cluster = self

# Extend cluster width to match the minimum distance required by NET0490
if cluster.width() < 2 * rid_version.min_obfuscation_distance_m:
delta = rid_version.min_obfuscation_distance_m - cluster.width() / 2
cluster = Cluster(
x_min=cluster.x_min - delta,
x_max=cluster.x_max + delta,
y_min=cluster.y_min,
y_max=cluster.y_max,
points=cluster.points,
)

# Extend cluster height to match the minimum distance required by NET0490
if cluster.height() < 2 * rid_version.min_obfuscation_distance_m:
delta = rid_version.min_obfuscation_distance_m - cluster.height() / 2
cluster = Cluster(
x_min=cluster.x_min,
x_max=cluster.x_max,
y_min=cluster.y_min - delta,
y_max=cluster.y_max + delta,
points=cluster.points,
)

# Extend cluster to the minimum area size required by NET0480
min_cluster_area = view_area_sqm * rid_version.min_cluster_size_percent / 100
if self.area() < min_cluster_area:
scale = math.sqrt(min_cluster_area / self.area()) / 2
cluster = Cluster(
x_min=self.x_min - scale * self.width(),
x_max=self.x_max + scale * self.width(),
y_min=self.y_min - scale * self.height(),
y_max=self.y_max + scale * self.height(),
points=self.points,
)

return cluster


def make_clusters(
flights: List[observation_api.Flight],
Expand Down Expand Up @@ -94,15 +128,13 @@ def make_clusters(

result: List[observation_api.Cluster] = []
for cluster in clusters:
cluster = cluster.extend(rid_version, view_area_sqm)

# Offset cluster
cluster = (
cluster.randomize()
) # TODO: Set random seed according to view extents so a static view will have static cluster subdivisions

min_cluster_area = view_area_sqm * rid_version.min_cluster_size_percent / 100
if cluster.area() < min_cluster_area:
# Extend cluster to the minimum area size required by NET0480
cluster = cluster.extend_size(min_cluster_area)

corners = LatLngRect(
geo.unflatten(view_min, (cluster.x_min, cluster.y_min)),
geo.unflatten(view_min, (cluster.x_max, cluster.y_max)),
Expand Down
9 changes: 9 additions & 0 deletions monitoring/monitorlib/rid.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ def min_cluster_size_percent(self) -> float:
else:
raise ValueError("Unsupported RID version '{}'".format(self))

@property
def min_obfuscation_distance_m(self) -> float:
if self == RIDVersion.f3411_19:
return v19.constants.NetMinObfuscationDistanceM
elif self == RIDVersion.f3411_22a:
return v22a.constants.NetMinObfuscationDistanceM
else:
raise ValueError("Unsupported RID version '{}'".format(self))

@property
def short_name(self) -> str:
if self == RIDVersion.f3411_19:
Expand Down

0 comments on commit 9083360

Please sign in to comment.