forecast trajectories don't transition, but remain and fade out
This commit is contained in:
parent
e837617e39
commit
9871848407
2 changed files with 65 additions and 45 deletions
|
@ -95,9 +95,7 @@ class Track:
|
|||
coords = self.get_projected_history(H)
|
||||
return [{"x":c[0], "y":c[1]} for c in coords]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class Frame:
|
||||
|
|
108
trap/renderer.py
108
trap/renderer.py
|
@ -24,11 +24,25 @@ from pyglet import shapes
|
|||
from PIL import Image
|
||||
|
||||
from trap.frame_emitter import DetectionState, Frame, Track
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
logger = logging.getLogger("trap.renderer")
|
||||
|
||||
@dataclass
|
||||
class LineAnimConfig:
|
||||
start_opacity: float
|
||||
target_opacity: float
|
||||
decay: float
|
||||
|
||||
@dataclass
|
||||
class AnimConfig:
|
||||
clear_color = (0,0,0,0)
|
||||
video_opacity = 100 # on 255 scale
|
||||
tracks: LineAnimConfig = LineAnimConfig(80, 180, 60)
|
||||
predictions: LineAnimConfig = LineAnimConfig(20, 50, 10)
|
||||
|
||||
|
||||
class FrameAnimation:
|
||||
def __init__(self, frame: Frame):
|
||||
self.start_time = time.time()
|
||||
|
@ -101,8 +115,8 @@ class DrawnTrack:
|
|||
'''
|
||||
# TODO: make lerp, currently quick way to get results
|
||||
for i, pos in enumerate(self.drawn_positions):
|
||||
self.drawn_positions[i][0] = int(exponentialDecay(self.drawn_positions[i][0], self.coords[i][0], 16, dt))
|
||||
self.drawn_positions[i][1] = int(exponentialDecay(self.drawn_positions[i][1], self.coords[i][1], 16, dt))
|
||||
self.drawn_positions[i][0] = int(exponentialDecay(self.drawn_positions[i][0], self.coords[i][0], AnimConfig.tracks.decay, dt))
|
||||
self.drawn_positions[i][1] = int(exponentialDecay(self.drawn_positions[i][1], self.coords[i][1], AnimConfig.tracks.decay, dt))
|
||||
|
||||
if len(self.coords) > len(self.drawn_positions):
|
||||
self.drawn_positions.extend(self.coords[len(self.drawn_positions):])
|
||||
|
@ -151,7 +165,7 @@ class DrawnTrack:
|
|||
if ci >= len(self.shapes):
|
||||
# TODO: add color2
|
||||
line = self.renderer.gradientLine(x, y, x2, y2, 3, color, color, batch=self.renderer.batch_anim)
|
||||
line.opacity = 5
|
||||
line.opacity = AnimConfig.tracks.start_opacity
|
||||
self.shapes.append(line)
|
||||
|
||||
else:
|
||||
|
@ -159,50 +173,53 @@ class DrawnTrack:
|
|||
line.x, line.y = x, y
|
||||
line.x2, line.y2 = x2, y2
|
||||
line.color = color
|
||||
line.opacity = int(exponentialDecay(line.opacity, 180, 3, dt))
|
||||
line.opacity = int(exponentialDecay(line.opacity, AnimConfig.tracks.target_opacity, AnimConfig.tracks.start_opacity, dt))
|
||||
|
||||
# TODO: basically a duplication of the above, do this smarter?
|
||||
# TODO: add intermediate segment
|
||||
color = colorset[self.track_id % len(colorset)]
|
||||
#color = colorset[self.track_id % len(colorset)]
|
||||
|
||||
for a, drawn_predictions in enumerate(self.drawn_predictions):
|
||||
if len(self.pred_shapes) <= a:
|
||||
self.pred_shapes.append([])
|
||||
for drawn_prediction in self.predictions:
|
||||
drawn_prediction.update_opacities(dt)
|
||||
|
||||
# for a, drawn_predictions in enumerate(self.drawn_predictions):
|
||||
# if len(self.pred_shapes) <= a:
|
||||
# self.pred_shapes.append([])
|
||||
|
||||
if len(self.pred_shapes[a]) > (len(drawn_predictions) +1):
|
||||
self.pred_shapes[a] = self.pred_shapes[a][:len(drawn_predictions)]
|
||||
# if len(self.pred_shapes[a]) > (len(drawn_predictions) +1):
|
||||
# self.pred_shapes[a] = self.pred_shapes[a][:len(drawn_predictions)]
|
||||
|
||||
# for i, pos in drawn_predictions.enumerate():
|
||||
for ci in range(0, len(drawn_predictions)):
|
||||
if ci == 0:
|
||||
x, y = [int(p) for p in self.drawn_positions[-1]]
|
||||
else:
|
||||
x, y = [int(p) for p in drawn_predictions[ci-1]]
|
||||
# # for i, pos in drawn_predictions.enumerate():
|
||||
# for ci in range(0, len(drawn_predictions)):
|
||||
# if ci == 0:
|
||||
# x, y = [int(p) for p in self.drawn_positions[-1]]
|
||||
# else:
|
||||
# x, y = [int(p) for p in drawn_predictions[ci-1]]
|
||||
|
||||
x2, y2 = [int(p) for p in drawn_predictions[ci]]
|
||||
# x2, y2 = [int(p) for p in drawn_predictions[ci]]
|
||||
|
||||
y, y2 = self.renderer.window.height - y, self.renderer.window.height - y2
|
||||
# color = [255,0,0]
|
||||
# print(x,y,x2,y2,color)
|
||||
# y, y2 = self.renderer.window.height - y, self.renderer.window.height - y2
|
||||
# # color = [255,0,0]
|
||||
# # print(x,y,x2,y2,color)
|
||||
|
||||
if ci >= len(self.pred_shapes[a]):
|
||||
# TODO: add color2
|
||||
line = self.renderer.gradientLine(x, y, x2, y2, 3, color, color, batch=self.renderer.batch_anim)
|
||||
line.opacity = 5
|
||||
self.pred_shapes[a].append(line)
|
||||
# if ci >= len(self.pred_shapes[a]):
|
||||
# # TODO: add color2
|
||||
# line = self.renderer.gradientLine(x, y, x2, y2, 3, color, color, batch=self.renderer.batch_anim)
|
||||
# line.opacity = 5
|
||||
# self.pred_shapes[a].append(line)
|
||||
|
||||
else:
|
||||
line = self.pred_shapes[a][ci-1]
|
||||
line.x, line.y = x, y
|
||||
line.x2, line.y2 = x2, y2
|
||||
line.color = color
|
||||
decay = (16/ci) if ci else 16
|
||||
half = len(drawn_predictions) / 2
|
||||
if ci < half:
|
||||
target_opacity = 180
|
||||
else:
|
||||
target_opacity = (1 - ((ci - half) / half)) * 180
|
||||
line.opacity = int(exponentialDecay(line.opacity, target_opacity, decay, dt))
|
||||
# else:
|
||||
# line = self.pred_shapes[a][ci-1]
|
||||
# line.x, line.y = x, y
|
||||
# line.x2, line.y2 = x2, y2
|
||||
# line.color = color
|
||||
# decay = (16/ci) if ci else 16
|
||||
# half = len(drawn_predictions) / 2
|
||||
# if ci < half:
|
||||
# target_opacity = 180
|
||||
# else:
|
||||
# target_opacity = (1 - ((ci - half) / half)) * 180
|
||||
# line.opacity = int(exponentialDecay(line.opacity, target_opacity, decay, dt))
|
||||
|
||||
class DrawnPrediction:
|
||||
def __init__(self, drawn_track: DrawnTrack, coords: list[list] = []):
|
||||
|
@ -245,13 +262,17 @@ class DrawnPrediction:
|
|||
# line.x, line.y = x, y
|
||||
# line.x2, line.y2 = x2, y2
|
||||
# line.color = color
|
||||
decay = (16/ci) if ci else 16
|
||||
|
||||
# lower decay for further points slows down fade in
|
||||
decay = (AnimConfig.predictions.decay/(3*ci)) if ci else AnimConfig.predictions.decay
|
||||
half = len(coords) / 2
|
||||
|
||||
if ci < half:
|
||||
target_opacity = 180
|
||||
target_opacity = AnimConfig.predictions.target_opacity
|
||||
else:
|
||||
target_opacity = (1 - ((ci - half) / half)) * 180
|
||||
target_opacity = (1 - ((ci - half) / half)) * AnimConfig.predictions.target_opacity
|
||||
line.opacity = int(exponentialDecay(line.opacity, target_opacity, decay, dt))
|
||||
# logger.info(f"{target_opacity=}, {line.opacity=}")
|
||||
|
||||
|
||||
class FrameWriter:
|
||||
|
@ -340,7 +361,8 @@ class Renderer:
|
|||
self.window.set_handler('on_refresh', self.on_refresh)
|
||||
self.window.set_handler('on_close', self.on_close)
|
||||
|
||||
pyglet.gl.glClearColor(81./255, 20/255, 46./255, 0)
|
||||
# Purple background color:
|
||||
pyglet.gl.glClearColor(*AnimConfig.clear_color)
|
||||
self.fps_display = pyglet.window.FPSDisplay(window=self.window, color=(255,255,255,255))
|
||||
self.fps_display.label.x = self.window.width - 50
|
||||
self.fps_display.label.y = self.window.height - 17
|
||||
|
@ -486,7 +508,7 @@ class Renderer:
|
|||
img = pyglet.image.ImageData(self.frame_size[0], self.frame_size[1], 'RGB', img.tobytes(), pitch=self.frame_size[0] * -1 * channels)
|
||||
# don't draw in batch, so that it is the background
|
||||
self.video_sprite = pyglet.sprite.Sprite(img=img, batch=self.batch_bg)
|
||||
self.video_sprite.opacity = 100
|
||||
self.video_sprite.opacity = AnimConfig.video_opacity
|
||||
except zmq.ZMQError as e:
|
||||
# idx = frame.index if frame else "NONE"
|
||||
# logger.debug(f"reuse video frame {idx}")
|
||||
|
|
Loading…
Reference in a new issue