Skip to content

Commit

Permalink
Created RawScanReading class
Browse files Browse the repository at this point in the history
Split off part ScanReading into RawScanReading to make modifying the raw distance values easier
  • Loading branch information
JoeBell committed Mar 3, 2025
1 parent 4c24da0 commit 11ff274
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 33 deletions.
2 changes: 1 addition & 1 deletion ExampleMultipleSonarReadings.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"readings:list[ScanReading] = []\n",
"for n,rays in enumerate(rays_list):\n",
" print(n + 1, len(rays_list), sep='/', end='\\r')\n",
" readings.append(SideScan(mesh).scan_rays(rays))\n",
" readings.append(ScanReading(SideScan(mesh).scan_rays(rays)))\n",
"\n",
"print()\n",
"\n",
Expand Down
9 changes: 5 additions & 4 deletions ExampleSingleSonarReading.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"source": [
"from Raytrace.TriangleMesh import Ray\n",
"from Raytrace.BVHMesh import BVHMesh\n",
"from Raytrace.SideScan import SideScan\n",
"from Raytrace.SideScan import SideScan, ScanReading\n",
"import numpy as np\n",
"import time"
]
Expand Down Expand Up @@ -43,10 +43,11 @@
"\n",
"rays = SideScan.generate_rays(orientation, min_angle, max_angle, sample_ray_count)\n",
"\n",
"reading = SideScan(mesh).scan_rays(rays)\n",
"raw_reading = SideScan(mesh).scan_rays(rays)\n",
"reading = ScanReading(raw_reading)\n",
"\n",
"print('Triangles:', mesh.triangles.shape[0])\n",
"reading.print_summary()"
"raw_reading.print_summary()"
]
},
{
Expand All @@ -56,7 +57,7 @@
"outputs": [],
"source": [
"import plotly.graph_objs as go\n",
"from PlotRays import plot_mesh, plot_rays, plot_reading"
"from Raytrace.PlotRays import plot_mesh, plot_rays, plot_reading"
]
},
{
Expand Down
10 changes: 5 additions & 5 deletions Raytrace/PlotRays.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ def plot_mesh(mesh:TriangleMesh, **kwargs) -> go.Mesh3d:
return go.Mesh3d(x=x, y=y, z=z, i=i, j=j, k=k, **kwargs)

def plot_rays(reading:ScanReading, **kwargs) -> go.Scatter3d:
origin = reading.origins[reading.finite]
inters = reading.intersections[reading.finite]
origin = reading.raw.origins[reading.raw.finite]
inters = reading.raw.intersections[reading.raw.finite]

x, y, z = np.stack((origin, inters, origin)).swapaxes(0,1).reshape((-1,3)).swapaxes(0,1)
return go.Scatter3d(x=x, y=y, z=z, **kwargs)
Expand All @@ -32,12 +32,12 @@ def plot_reading(reading:ScanReading) -> go.Figure:
'mode': 'markers',
'name': 'Raw',
'showlegend': True,
'x': reading.distances[reading.finite],
'y': np.zeros(reading.intersection_count),
'x': reading.raw.distances[reading.raw.finite],
'y': np.zeros(reading.raw.intersection_count),
})
])
def plot_intersections(reading:ScanReading, **kwargs) -> go.Scatter3d:
inters = reading.intersections[reading.finite]
inters = reading.raw.intersections[reading.raw.finite]

x, y, z = inters.reshape((-1,3)).swapaxes(0,1)
return go.Scatter3d(x=x, y=y, z=z, **kwargs)
Expand Down
55 changes: 32 additions & 23 deletions Raytrace/SideScan.py
Original file line number Diff line number Diff line change
@@ -1,62 +1,71 @@
from Raytrace.TriangleMesh import TriangleMesh, Ray
from typing import Self
import numpy as np
import time

class ScanReading:
class RawScanReading:
distances:np.ndarray
intersections:np.ndarray
origins:np.ndarray
directions:np.ndarray
finite:np.ndarray
intersection_count:int

start_time:float = -1
end_time:float = -1

def __init__(self, distances:np.ndarray, rays:list[Ray]):
old_error_state = np.seterr(all='ignore')
self.distances = distances
self.origins = np.array([r.origin for r in rays])
self.directions = np.array([r.direction for r in rays])
self.intersections = self.origins + self.directions * self.distances.reshape((-1,1))
self.finite = np.isfinite(self.distances)
self.intersection_count = np.count_nonzero(self.finite)
np.seterr(**old_error_state)

def print_summary(self) -> None:
print('Intersections:', self.intersection_count , '/', len(self.distances))
if self.end_time == -1 or self.start_time == -1: return
print('Time:', self.end_time - self.start_time, 'seconds')
print('Speed:', len(self.distances)/(self.end_time - self.start_time), 'rays/seconds')

class ScanReading:
raw:RawScanReading

smooth_dist:float
result_reselution:int
min_dist:float
max_dist:float

result:np.ndarray

start_time:float = -1
end_time:float = -1

def __init__(self,
distances:np.ndarray, rays:list[Ray],
raw_reading:RawScanReading,
smooth_dist:float = 0.05,
result_reselution:int = 1000,
min_dist:float = 0,
max_dist:float = 2
):
old_error_state = np.seterr(all='ignore')
self.distances = distances
self.origins = np.array([r.origin for r in rays])
self.directions = np.array([r.direction for r in rays])
self.intersections = self.origins + self.directions * self.distances.reshape((-1,1))
self.finite = np.isfinite(self.distances)
self.intersection_count = np.count_nonzero(self.finite)

self.raw = raw_reading
self.smooth_dist = smooth_dist
self.result_reselution = result_reselution
self.min_dist = min_dist
self.max_dist = max_dist
self.convert_distances()
self.process_raw()
np.seterr(**old_error_state)

def convert_distances(self) -> None:
def process_raw(self) -> None:
old_error_state = np.seterr(all='ignore')
norm = (self.distances[self.finite] - self.min_dist) / (self.max_dist - self.min_dist)
norm = (self.raw.distances[self.raw.finite] - self.min_dist) / (self.max_dist - self.min_dist)

ldist = norm - (np.arange(0,1,1/self.result_reselution) + 0.5/self.result_reselution).reshape((-1,1))
smooth_val = self.smooth_dist / (self.max_dist - self.min_dist)
lval = np.pow(np.maximum(0, np.square(smooth_val) - np.square(ldist)),3) / (32/35*smooth_val**7) / len(self.distances)
lval = np.pow(np.maximum(0, np.square(smooth_val) - np.square(ldist)),3) / (32/35*smooth_val**7) / len(self.raw.distances)

self.result = np.sum(lval, axis = 1)
np.seterr(**old_error_state)
def print_summary(self) -> None:
print('Intersections:', self.intersection_count , '/', len(self.distances))
if self.end_time == -1 or self.start_time == -1: return
print('Time:', self.end_time - self.start_time, 'seconds')
print('Speed:', len(self.distances)/(self.end_time - self.start_time), 'rays/seconds')
class SideScan:
mesh:TriangleMesh
smooth_dist:float
Expand All @@ -65,15 +74,15 @@ def __init__(self, mesh:TriangleMesh, smooth_dist:float = 0.05, result_reselutio
self.mesh = mesh
self.smooth_dist = smooth_dist
self.result_reselution = result_reselution
def scan_rays(self, rays:list[Ray]) -> ScanReading:
def scan_rays(self, rays:list[Ray]) -> RawScanReading:
distances = np.empty((len(rays),), np.float32)

start_time = time.time()
for n, ray in enumerate(rays):
distances[n] = self.mesh.raytrace(ray)
end_time = time.time()

out = ScanReading(distances, rays)
out = RawScanReading(distances, rays)

out.start_time = start_time
out.end_time = end_time
Expand Down

0 comments on commit 11ff274

Please sign in to comment.