From 8dcf70959b64746124243f263f845d95489aca4d Mon Sep 17 00:00:00 2001 From: Ruben van de Ven Date: Wed, 12 Nov 2025 23:05:04 +0100 Subject: [PATCH] For dortmund --- README.md | 2 + SETTINGS/2025-11-dortmund/trajectron.json | 10 +- supervisord.conf | 3 +- tests/stage_lines.ipynb | 123 +++++++++++++++------- trap/base.py | 5 +- trap/cv_renderer.py | 6 +- trap/lidar_tracker.py | 35 +++--- trap/lines.py | 1 + trap/node.py | 5 +- trap/prediction_server.py | 62 ++++++++--- trap/process_data.py | 5 +- trap/stage.py | 68 ++++++++---- trap/stage_renderer.py | 73 ++++++++----- trap/track_writer.py | 32 ++++-- trap/tracker.py | 75 ++++++++++++- 15 files changed, 368 insertions(+), 137 deletions(-) diff --git a/README.md b/README.md index 56d84fd..38e6da7 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,8 @@ These are roughly the steps to go from datagathering to training * See [[tests/trajectron_maps.ipynb]] for more info how to do so (e.g. the homography map/scale settings, which are also set in process_data) 5. Train Trajectron model `uv run trajectron_train --eval_every 10 --vis_every 1 --train_data_dict NAME_train.pkl --eval_data_dict NAME_val.pkl --offline_scene_graph no --preprocess_workers 8 --log_dir EXPERIMENTS/models --log_tag _NAME --train_epochs 100 --conf EXPERIMENTS/config.json --batch_size 256 --data_dir EXPERIMENTS/trajectron-data ` + * For faster training disalble edges: + ` uv run trajectron_train --eval_every 200 --train_data_dict dortmund-nostep-nosmooth-noise2-offsets1-f2.0-map-2025-11-11_train.pkl --eval_data_dict dortmund-nostep-nosmooth-noise2-offsets1-f2.0-map-2025-11-11_val.pkl --offline_scene_graph no --preprocess_workers 8 --log_dir /home/ruben/suspicion/trap/SETTINGS/2025-11-dortmund/models --log_tag _dortmund-nostep-nosmooth-noise2-offsets1-f2.0-map-2025-11-11 --train_epochs 100 --conf /home/ruben/suspicion/trap/SETTINGS/2025-11-dortmund/trajectron.json --data_dir SETTINGS/2025-11-dortmund/trajectron --map_encoding --no_edge_encoding --dynamic_edges yes --no_edge_encoding --edge_influence_combine_method max --batch_size 512` 6. The run! * `uv run supervisord` 22\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mline_prediction\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget\u001b[49m\u001b[43m(\u001b[49m\u001b[43mStartFromClosestPoint\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mfrom_point)\n\u001b[1;32m 23\u001b[0m fig, ax \u001b[38;5;241m=\u001b[39m plt\u001b[38;5;241m.\u001b[39msubplots()\n\u001b[1;32m 24\u001b[0m render(line_history, ax)\n", + "File \u001b[0;32m~/suspicion/trap/trap/lines.py:1537\u001b[0m, in \u001b[0;36mLineAnimationStack.get\u001b[0;34m(self, anim)\u001b[0m\n\u001b[1;32m 1534\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m anim \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstack:\n\u001b[1;32m 1535\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstack[anim]\n\u001b[0;32m-> 1537\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mRuntimeError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNot in line stack \u001b[39m\u001b[38;5;132;01m{\u001b[39;00manim\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n", + "\u001b[0;31mRuntimeError\u001b[0m: Not in line stack StartFromClosestPoint" + ] } ], "source": [ @@ -895,7 +897,7 @@ "\n", "\n", "def render(line: LineAnimationStack, ax: Axes):\n", - " rl = line.as_renderable_line(1)\n", + " rl = line.as_renderable_line(.02)\n", " points = np.array([p.position for p in rl.points])\n", "\n", " colors = np.array([tuple(p.color.as_array()) for p in rl.points])\n", @@ -905,7 +907,7 @@ " lc = LineCollection(segments, colors=colors[:-1], linewidth=2)\n", " \n", " ax.add_collection(lc)\n", - " ax.scatter(points[:, 0], points[:, 1], c=colors, s=10)\n", + " ax.scatter(points[:, 0], points[:, 1], c=colors, s=4)\n", " \n", " # plt.scatter(closeby[:,0], closeby[:,1], c=colors, alpha=1)\n", "\n", @@ -919,7 +921,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 28, "id": "3aa9d65f", "metadata": {}, "outputs": [ @@ -929,7 +931,7 @@ "(1.0, 2.0)" ] }, - "execution_count": 8, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -955,6 +957,49 @@ "execution_count": null, "id": "8c248325", "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "line2 = [[0, -i/10] for i in range(0,1000)]\n", + "line1 = [[(i/3)**2, 0] for i in range(0,1000)]\n", + "# line3 = [[i/3, -1*(i/10)**2] for i in range(0,1000)]\n", + "\n", + "# print(line3)\n", + "\n", + "\n", + "line_prediction = LineAnimationStack(StaticLine(line1, prediction_color))\n", + "line_prediction.add(RotatingLine(line_prediction.tail, decay_speed=2))\n", + "\n", + "line_prediction.start()\n", + "\n", + "fig, ax = plt.subplots()\n", + "for i in range(40):\n", + " render(line_prediction, ax)\n", + " line_prediction.root.points = line2\n", + "\n", + " if (i+1) % 10 == 0:\n", + " print('switch')\n", + " fig, ax = plt.subplots()\n", + " line_prediction.root.color = history_color\n", + " line_prediction.root.points = line3\n", + " line_prediction.start()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1427d291", + "metadata": {}, "outputs": [], "source": [] } diff --git a/trap/base.py b/trap/base.py index 0ad07f0..ca6273f 100644 --- a/trap/base.py +++ b/trap/base.py @@ -74,6 +74,7 @@ class DetectionState(IntFlag): Confirmed = 2 # after tentative Lost = 4 # lost when DeepsortTrack.time_since_update > 0 but not Deleted Interpolated = 8 # A position estimated through interpolation of adjecent detections + # Interpolated = 8 # A position estimated through interpolation of adjecent detections @classmethod def from_deepsort_track(cls, track: DeepsortTrack): @@ -89,11 +90,13 @@ class DetectionState(IntFlag): def from_bytetrack_track(cls, track: ByteTrackTrack): if track.state == ByteTrackTrackState.New: return cls.Tentative - if track.state == ByteTrackTrackState.Lost: + if track.state == ByteTrackTrackState.Removed: return cls.Lost # if track.time_since_update > 0: if track.state == ByteTrackTrackState.Tracked: return cls.Confirmed + if track.state == ByteTrackTrackState.Lost: + return cls.Tentative raise RuntimeError("Should not run into Deleted entries here") diff --git a/trap/cv_renderer.py b/trap/cv_renderer.py index a83e133..6d80a0c 100644 --- a/trap/cv_renderer.py +++ b/trap/cv_renderer.py @@ -18,7 +18,7 @@ import pyglet import zmq from pyglet import shapes -from trap.base import Detection +from trap.base import Detection, UndistortedCamera from trap.counter import CounterListerner from trap.frame_emitter import Frame, Track from trap.lines import load_lines_from_svg @@ -151,10 +151,12 @@ class CvRenderer(Node): # logger.debug(f'new video frame {frame.index}') - if self.frame is None: + if self.frame is None and i < 100: # might need to wait a few iterations before first frame comes available time.sleep(.1) continue + else: + self.frame = Frame(i, np.zeros((1920,1080,3)), camera=UndistortedCamera(12)) try: prediction_frame: Frame = self.prediction_sock.recv_pyobj(zmq.NOBLOCK) diff --git a/trap/lidar_tracker.py b/trap/lidar_tracker.py index 70455e3..860e359 100644 --- a/trap/lidar_tracker.py +++ b/trap/lidar_tracker.py @@ -208,6 +208,7 @@ class Lidar(Node): self.track_sock = self.pub(self.config.zmq_trajectory_addr) self.detection_sock = self.pub(self.config.zmq_detection_addr) + self.lost_track_sock = self.pub(self.config.zmq_lost_addr) calibration = vd.Calibration.read( "VLP-16.yaml") config = vd.Config(model=vd.Model.VLP16, calibration=calibration) @@ -286,12 +287,12 @@ class Lidar(Node): self.map_outline_volume.bounding_polygon = o3d.utility.Vector3dVector(polygon_points) - if self.config.smooth_tracks: - # TODO)) make configurable - logger.info(f"Smoother enabled, assuming {ASSUMED_FPS} fps") - self.smoother = Smoother(window_len=int(ASSUMED_FPS*.6), convolution=True) - else: - logger.info("Smoother Disabled (enable with --smooth-tracks)") + # if self.config.smooth_tracks: + # # TODO)) make configurable + # logger.info(f"Smoother enabled, assuming {ASSUMED_FPS} fps") + # self.smoother = Smoother(window_len=int(ASSUMED_FPS*.6), convolution=True) + # else: + # logger.info("Smoother Disabled (enable with --smooth-tracks)") self.remotes = {} @@ -487,7 +488,7 @@ class Lidar(Node): filtered_pcd = denoised_pcd # down sample - filtered_pcd = filtered_pcd.voxel_down_sample(voxel_size=0.04) + filtered_pcd = filtered_pcd.voxel_down_sample(voxel_size=0.06) stat_downsampled = len(filtered_pcd.points) timers.append(('downsample', time.perf_counter())) @@ -527,7 +528,8 @@ class Lidar(Node): self.logger.debug(f"online tracks: {[t[4] for t in online_tracks]}") removed_tracks = self.tracker.removed_stracks # active_stracks = [track for track in self.tracker.tracked_stracks if track.is_activated] - active_stracks = [track for track in self.tracker.tracked_stracks if track.is_activated] + # we want both the lost, and currently visible, as otherwise, the predictor goes haywire + active_stracks = [track for track in (self.tracker.tracked_stracks + self.tracker.lost_stracks) if track.is_activated] detections = [Detection.from_bytetrack(track, frame_idx) for track in active_stracks] counter.set('detections', len(detections)) @@ -549,6 +551,7 @@ class Lidar(Node): for t in removed_tracks: if t.track_id in self.tracks: if t.is_activated: + self.lost_track_sock.send_pyobj(self.tracks[t.track_id]) self.logger.info(f"Lost track: {t.track_id}") del self.tracks[t.track_id] # TODO: fix this oddity: @@ -567,8 +570,8 @@ class Lidar(Node): frame = Frame(frame_idx, None, time.time(), active_tracks, camera.H, camera) - if self.config.smooth_tracks: - frame = self.smoother.smooth_frame_tracks(frame) + # if self.config.smooth_tracks: + # frame = self.smoother.smooth_frame_tracks(frame) timers.append(('smooth', time.perf_counter())) @@ -669,6 +672,10 @@ class Lidar(Node): help='Manually specity communication addr for the trajectory messages', type=str, default="ipc:///tmp/feeds_traj") + argparser.add_argument('--zmq-lost-addr', + help='Manually specity communication addr for the trajectory messages', + type=str, + default="ipc:///tmp/feeds_lost") argparser.add_argument('--zmq-detection-addr', help='Manually specity communication addr for the detection messages', type=str, @@ -698,9 +705,9 @@ class Lidar(Node): help='Maximum area (m2) of bounding boxes to consider them for tracking', type=float, default=2) - argparser.add_argument("--smooth-tracks", - help="Smooth the tracker tracks before sending them to the predictor", - action='store_true') + # argparser.add_argument("--smooth-tracks", + # help="Smooth the tracker tracks before sending them to the predictor", + # action='store_true') argparser.add_argument("--viz", help="Render pointclouds in open3d", action='store_true') @@ -902,7 +909,7 @@ def get_cluster_boxes(clusters, min_area = 0, max_area=5): area = (x_max-x_min) * (y_max - y_min) if area < min_area or area > max_area: - logger.warning(f"Dropping box {area} ") + logger.debug(f"Dropping box {area} ") continue diff --git a/trap/lines.py b/trap/lines.py index 5b6e56d..0becab2 100644 --- a/trap/lines.py +++ b/trap/lines.py @@ -1198,6 +1198,7 @@ class RotatingLine(LineAnimator): # find closest point to start from: origin = target_line.points[0] + # print(origin, target_line.points[-1]) # closest_idx = StartFromClosestPoint.find_closest_to_point(origin.position, [p.position for p in self.drawn_points]) # if closest_idx: # print('cut at', closest_idx) diff --git a/trap/node.py b/trap/node.py index 49e5108..f21b99f 100644 --- a/trap/node.py +++ b/trap/node.py @@ -161,6 +161,7 @@ class Node(): def push(self, addr: str): "push-pull pair" sock = self.zmq_context.socket(zmq.PUSH) + # sock.setsockopt(zmq.LINGER, 0) sock.connect(addr) return sock @@ -210,5 +211,7 @@ def setup_logging(config: Namespace): logging.basicConfig( level=loglevel, - handlers=log_handlers # [queue_handler] + handlers=log_handlers, # [queue_handler] + format="%(asctime)s %(levelname)s:%(name)s:%(message)s", + datefmt="%H:%M:%S" ) \ No newline at end of file diff --git a/trap/prediction_server.py b/trap/prediction_server.py index 2275388..4cbadc1 100644 --- a/trap/prediction_server.py +++ b/trap/prediction_server.py @@ -13,6 +13,7 @@ from multiprocessing import Event import dill import numpy as np +import shapely import torch import zmq from trajectron.environment import Environment, Scene, GeometricMap @@ -21,6 +22,7 @@ from trajectron.model.online.online_trajectron import OnlineTrajectron from trajectron.utils import prediction_output_to_trajectories from trap.frame_emitter import DataclassJSONEncoder, Frame +from trap.lines import load_lines_from_svg from trap.node import Node from trap.tracker import Smoother from trap.utils import ImageMap @@ -52,14 +54,16 @@ def create_online_env(env, hyperparams, scene_idx, init_timestep): init_timestep + 1), state=hyperparams['state']) online_scene.robot = test_scene.robot - online_scene.calculate_scene_graph(attention_radius=env.attention_radius, + radius = {k: 0 for k,v in env.attention_radius.items()} + + online_scene.calculate_scene_graph(attention_radius=radius, edge_addition_filter=hyperparams['edge_addition_filter'], edge_removal_filter=hyperparams['edge_removal_filter']) return Environment(node_type_list=env.node_type_list, standardization=env.standardization, scenes=[online_scene], - attention_radius=env.attention_radius, + attention_radius=radius, robot_type=env.robot_type) @@ -161,6 +165,15 @@ class PredictionServer(Node): self.trajectory_socket = self.sub(self.config.zmq_trajectory_addr) self.prediction_socket = self.pub(self.config.zmq_prediction_addr) self.external_predictions = not self.config.zmq_prediction_addr.startswith("ipc://") + + self.cutoff_shape = None + if self.config.cutoff_map: + + self.cutoff_line = load_lines_from_svg(self.config.cutoff_map, 100, '')[0] + self.cutoff_shape = shapely.Polygon([p.position for p in self.cutoff_line.points]) + + logger.info(f"{self.cutoff_shape}") + def send_frame(self, frame: Frame): @@ -184,7 +197,8 @@ class PredictionServer(Node): # model_dir = 'models/models_04_Oct_2023_21_04_48_eth_vel_ar3' # Load hyperparameters from json - config_file = os.path.join(self.config.model_dir, self.config.conf) + # config_file = os.path.join(self.config.model_dir, self.config.conf) + config_file = self.config.conf if not os.path.exists(config_file): raise ValueError('Config json not found!') with open(config_file, 'r') as conf_json: @@ -224,6 +238,9 @@ class PredictionServer(Node): logger.info(f"Basing online env on {eval_scene=} -- loaded from {self.config.eval_data_dict}") online_env = create_online_env(eval_env, hyperparams, scene_idx, init_timestep) + print("overriding attention radius") + online_env.attention_radius = {(online_env.NodeType.PEDESTRIAN, online_env.NodeType.PEDESTRIAN): 0.1} + # auto-find highest iteration model_registrar = ModelRegistrar(self.config.model_dir, self.config.eval_device) model_iterations = pathlib.Path(self.config.model_dir).glob('model_registrar-*.pt') @@ -297,6 +314,7 @@ class PredictionServer(Node): input_dict = {} for identifier, track in frame.tracks.items(): + # if len(trajectory['history']) < 7: # # TODO: these trajectories should still be in the output, but without predictions # continue @@ -313,7 +331,16 @@ class PredictionServer(Node): if len(track.history) < 2: continue + + node = track.to_trajectron_node(frame.camera, online_env) + + if self.cutoff_shape: + position = shapely.Point(node.data.data[-1][:2]) + if not shapely.contains(self.cutoff_shape, position): + # logger.debug(f"Skip position {position}") + continue + # print(node.data.data[-1]) input_dict[node] = np.array(object=node.data.data[-1]) # print("history", node.data.data[-10:]) @@ -352,6 +379,7 @@ class PredictionServer(Node): # ) # input_dict[node] = np.array(object=[x[-1],y[-1],vx[-1],vy[-1],ax[-1],ay[-1]]) + # break # only on # print(input_dict) @@ -368,9 +396,11 @@ class PredictionServer(Node): continue maps = None + start_maps = time.time() if hyperparams['use_map_encoding']: maps = get_maps_for_input(input_dict, eval_scene, hyperparams, device=self.config.eval_device) + # print(maps) # robot_present_and_future = None @@ -398,7 +428,8 @@ class PredictionServer(Node): gmm_mode=self.config.gmm_mode, # "If True: The mode of the Gaussian Mixture Model (GMM) is sampled (see trajectron.model.mgcvae.py)" z_mode=self.config.z_mode # "Predictions from the model’s most-likely high-level latent behavior mode" (see trajecton.models.components.discrete_latent:sample_p(most_likely_z=z_mode)) ) - + print(len(dists), len (preds)) + intermediate = time.time() # unsure what this bit from online_prediction.py does: # detailed_preds_dict = dict() # for node in eval_scene.nodes: @@ -418,8 +449,8 @@ class PredictionServer(Node): end = time.time() - logger.debug("took %.2f s (= %.2f Hz) w/ %d nodes and %d edges -- init: %.2f s" % (end - start, - 1. / (end - start), len(trajectron.nodes), + logger.debug("took %.2f s (= %.2f Hz), maps: %.2f, forward: %.2f w/ %d nodes and %d edges -- init: %.2f s" % (end - start, + 1. / (end - start), (start-start_maps)/(end - start), (intermediate-start)/(end - start), len(trajectron.nodes), trajectron.scene_graph.get_num_edges(), start-t_init)) # if self.config.center_data: @@ -441,7 +472,7 @@ class PredictionServer(Node): futures_dict = futures_dict[ts_key] response = {} - logger.debug(f"{histories_dict=}") + # logger.debug(f"{histories_dict=}") for node in histories_dict: history = histories_dict[node] # future = futures_dict[node] # ground truth dict @@ -509,9 +540,9 @@ class PredictionServer(Node): # default='../Trajectron-plus-plus/experiments/pedestrians/models/models_04_Oct_2023_21_04_48_eth_vel_ar3') inference_parser.add_argument("--conf", - help="path to json config file for hyperparameters, relative to model_dir", - type=str, - default='config.json') + help="path to json config file for hyperparameters", + type=pathlib.Path, + default='EXPERIMENTS/config.json') # Model Parameters (hyperparameters) inference_parser.add_argument("--offline_scene_graph", @@ -566,12 +597,12 @@ class PredictionServer(Node): inference_parser.add_argument('--batch_size', help='training batch size', type=int, - default=256) + default=512) inference_parser.add_argument('--k_eval', help='how many samples to take during evaluation', type=int, - default=25) + default=1) # Data Parameters inference_parser.add_argument("--eval_data_dict", @@ -593,7 +624,7 @@ class PredictionServer(Node): inference_parser.add_argument("--eval_device", help="what device to use during inference", type=str, - default="cpu") + default="cuda:0") inference_parser.add_argument('--seed', @@ -634,6 +665,11 @@ class PredictionServer(Node): help="Center data around cx and cy. Should also be used when processing data", action='store_true') + inference_parser.add_argument('--cutoff-map', + help='specify a map (svg-file) that specifies projection boundaries. In here, degrade chance to be selectede', + type=str, + default="../DATASETS/hof-lidar/map_hof.svg") + return inference_parser diff --git a/trap/process_data.py b/trap/process_data.py index c7868f9..3ed30a3 100644 --- a/trap/process_data.py +++ b/trap/process_data.py @@ -106,6 +106,8 @@ def process_data(src_dir: Path, dst_dir: Path, name: str, smooth_tracks: bool, n if map_img_path: if not map_img_path.exists(): raise RuntimeError(f"Map image does not exists {map_img_path}") + + print(f"Using map {map_img_path}") type_map = {} # TODO)) For now, assume the map is a 100x scale of the world coordinates (i.e. 100px per meter) @@ -358,7 +360,8 @@ def process_data(src_dir: Path, dst_dir: Path, name: str, smooth_tracks: bool, n --train_epochs 100 \\ --conf {target_config} \\ --data_dir {dst_dir} \\ - {"--map_encoding" if map_img_path else ""} + {"--map_encoding" if map_img_path else ""} \\ + --no_edge_encoding """) return names diff --git a/trap/stage.py b/trap/stage.py index 2248fa1..d86e278 100644 --- a/trap/stage.py +++ b/trap/stage.py @@ -75,9 +75,9 @@ class SceneInfo: class ScenarioScene(Enum): DETECTED = SceneInfo(4, "First detection") - SUBSTANTIAL = SceneInfo(6, "Multiple detections") - FIRST_PREDICTION = SceneInfo(10, "Prediction is ready") - CORRECTED_PREDICTION = SceneInfo(11, "Multiple predictions") + TRACKED = SceneInfo(6, "Multiple detections") + PREDICTION_AVAILABLE = SceneInfo(10, "Prediction is ready") + UPDATED_PREDICTION = SceneInfo(11, "Multiple predictions") LOITERING = SceneInfo(7, "Foundto be loitering", takeover_possible=True, takeover_possible_after=10) # TODO: create "possible after" PLAY = SceneInfo(7, description="After many predictions; just fooling around", takeover_possible=True, takeover_possible_after=10) LOST = SceneInfo(-1, description="Track lost", takeover_possible=True, takeover_possible_after=0) @@ -166,6 +166,7 @@ class Scenario(PrioritySlotItem): def get_priority(self) -> int: # newer higher prio distance = 0 + # todo: check if last point is within bounds if self.track and len(self.track.projected_history) > 5: distance = np.linalg.norm(self.track.projected_history[-1] - self.track.projected_history[0]) return (self.scene.value.priority, distance) @@ -261,17 +262,17 @@ class Scenario(PrioritySlotItem): def check_track(self): predictions = len(self.prediction_tracks) if predictions and self.running_for() < 20: - self.set_scene(ScenarioScene.FIRST_PREDICTION) + self.set_scene(ScenarioScene.PREDICTION_AVAILABLE) return True - if predictions and self.running_for() > 120: + if predictions and self.running_for() > 60 * 5: self.set_scene(ScenarioScene.PLAY) return True if predictions: - self.set_scene(ScenarioScene.CORRECTED_PREDICTION) + self.set_scene(ScenarioScene.UPDATED_PREDICTION) return True if self.track: - if len(self.track.projected_history) > TRACK_ASSUMED_FPS * 3: - self.set_scene(ScenarioScene.SUBSTANTIAL) + if len(self.track.projected_history) > TRACK_ASSUMED_FPS * 2: + self.set_scene(ScenarioScene.TRACKED) else: self.set_scene(ScenarioScene.DETECTED) return True @@ -360,7 +361,7 @@ class DrawnScenario(Scenario): self.line_history = LineAnimationStack(history) self.line_history.add(AppendableLineAnimator(self.line_history.tail, draw_decay_speed=120, transition_in_on_init=False)) self.line_history.add(CropLine(self.line_history.tail, self.MAX_HISTORY)) - self.line_history.add(SimplifyLine(self.line_history.tail, 0.003)) # Simplify before effects, so they don't distort + self.line_history.add(SimplifyLine(self.line_history.tail, 0.002)) # Simplify before effects, so they don't distort self.line_history.add(FadedTailLine(self.line_history.tail, TRACK_FADE_AFTER_DURATION * TRACK_ASSUMED_FPS, TRACK_END_FADE)) self.line_history.add(NoiseLine(self.line_history.tail, amplitude=0, t_factor=.3)) self.line_history.add(FadeOutJitterLine(self.line_history.tail, frequency=5, t_factor=.5)) @@ -373,9 +374,9 @@ class DrawnScenario(Scenario): self.line_prediction.get(StartFromClosestPoint).skip=True self.line_prediction.add(RotatingLine(self.line_prediction.tail, decay_speed=16)) self.line_prediction.get(RotatingLine).skip = False - self.line_prediction.add(SegmentLine(self.line_prediction.tail, duration=7, anim_f=SegmentLine.anim_follow_in_front)) + self.line_prediction.add(SegmentLine(self.line_prediction.tail, duration=7 / 3, anim_f=SegmentLine.anim_follow_in_front)) self.line_prediction.get(SegmentLine).skip = False - self.line_prediction.add(SimplifyLine(self.line_prediction.tail, 0.003)) # Simplify before effects, so they don't distort + self.line_prediction.add(SimplifyLine(self.line_prediction.tail, 0.002)) # Simplify before effects, so they don't distort GAP_DURATION = 5 def dash_len(dt, t): t=min(1, t/GAP_DURATION) @@ -573,7 +574,10 @@ class DrawnScenario(Scenario): original = self.scene.name changed = super().set_scene(scene) if changed: - self.stage.log_sock.send_string(f"Change {self.track_id}: {original} -> {self.scene.name}") + try: + self.stage.log_sock.send_string(f"Visitor {self.track_id}: {original} -> {self.scene.name}", zmq.NOBLOCK) + except Exception as e: + logger.warning("Not sent the scene change message, broken socket?") return changed class NoTracksScenario(PrioritySlotItem): @@ -622,12 +626,23 @@ class DebugDrawer(): def __init__(self, stage: Stage): self.stage = stage - def to_renderable_lines(self, dt: DeltaT): + def positions_to_renderable_lines(self, dt: DeltaT): lines = RenderableLines([], CoordinateSpace.WORLD) past_color = SrgbaColor(1,0,1,1) - future_color = SrgbaColor(0,1,0,1) + current_color = SrgbaColor(1,0,0,.6) for scenario in self.stage.scenarios.values(): - lines.append(StaticLine(scenario.track.projected_history, past_color).as_renderable_line(dt)) + # lines.append(StaticLine(scenario.track.projected_history, past_color).as_renderable_line(dt).as_simplified(factor=.005)) + center = scenario.track.projected_history[-1] + + lines.append(StaticLine([[center[0], center[1]-.2], [center[0], center[1]+.2]], current_color).as_renderable_line(dt)) + lines.append(StaticLine([[center[0]-.2, center[1]], [center[0]+.2, center[1]]], current_color).as_renderable_line(dt)) + return lines + + def predictions_to_renderable_lines(self, dt: DeltaT): + lines = RenderableLines([], CoordinateSpace.WORLD) + future_color = SrgbaColor(0,1,0,.6) + for scenario in self.stage.scenarios.values(): + # lines.append(StaticLine(scenario.track.projected_history, past_color).as_renderable_line(dt).as_simplified(factor=.005)) if scenario.active_ptrack: lines.append(StaticLine(scenario.active_ptrack._track.predictions[0], future_color).as_renderable_line(dt)) return lines @@ -639,7 +654,8 @@ class DatasetDrawer(): line_color = SrgbaColor(0,1,1,1) self.track_line = LineAnimationStack(StaticLine([], line_color)) - self.track_line.add(SimplifyLine(self.track_line.tail, 0.004)) # Simplify before cropping, to get less noodling + # self.track_line.add(SimplifyLine(self.track_line.tail, 0.004)) # Simplify before cropping, to get less noodling + self.track_line.add(SimplifyLine(self.track_line.tail, 0.002)) # no laser in dortmund self.track_line.add(CropAnimationLine(self.track_line.tail, 50, assume_fps=TRACK_ASSUMED_FPS*20)) # speed up # self.track_line.add(DashedLine(self.track_line.tail, t_factor=4, loop_offset=True)) @@ -653,11 +669,14 @@ class DatasetDrawer(): def to_renderable_lines(self, dt: DeltaT): lines = RenderableLines([], CoordinateSpace.WORLD) if not self.track_line.is_running(): + # print('update') track_id = random.choice(list(self.stage.history.state.tracks.keys())) # print('track_id', track_id) positions = self.stage.history.state.track_histories[track_id] self.track_line.root.points = positions self.track_line.start() + # else: + # print('-') lines.lines.append( self.track_line.as_renderable_line(dt) @@ -795,9 +814,11 @@ class Stage(Node): # TODO: sometimes very slow! t1 = time.perf_counter() training_lines = self.auxilary.to_renderable_lines(dt) - all_active_tracks = self.debug_drawer.to_renderable_lines(dt) - t2 = time.perf_counter() + active_positions = self.debug_drawer.positions_to_renderable_lines(dt) + all_predictions = self.debug_drawer.predictions_to_renderable_lines(dt) + + t2b = time.perf_counter() timings = [] for scenario in self.active_scenarios: @@ -807,7 +828,7 @@ class Stage(Node): if not len(self.active_scenarios): lines = training_lines - t2b = time.perf_counter() + t2c = time.perf_counter() # rl_scenario = lines.as_simplified(SimplifyMethod.RDP, .003) # or segmentise (see shapely) # rl_training = training_lines.as_simplified(SimplifyMethod.RDP, .003) # or segmentise (see shapely) self.counter.set("stage.lines", len(lines.lines)) @@ -820,7 +841,8 @@ class Stage(Node): 1: lines, 2: self.debug_lines, 3: training_lines, - 4: all_active_tracks, + 4: active_positions, + 5: all_predictions, } t4 = time.perf_counter() @@ -836,7 +858,7 @@ class Stage(Node): t6 = time.perf_counter() - t = (t2-t1, t3-t2b, t2b-t2, t4-t3, t5-t4, t6-t5) + t = (t2-t1, t2b-t2, t2c-t2b, t3-t2c, t2b-t2, t4-t3, t5-t4, t6-t5) if sum(t) > .1: print(t) print(len(lines.lines)) @@ -883,6 +905,10 @@ class Stage(Node): help='specify a map (svg-file) from which to load lines which will be overlayed', type=str, default="../DATASETS/hof-lidar/map_hof.svg") + argparser.add_argument('--cutoff-map', + help='specify a map (svg-file) that specifies projection boundaries. In here, degrade chance to be selectede', + type=str, + default="../DATASETS/hof-lidar/map_hof.svg") argparser.add_argument('--max-active-scenarios', help='Maximum number of active scenarios that can be drawn at once (to not overlod the laser)', type=int, diff --git a/trap/stage_renderer.py b/trap/stage_renderer.py index ed01d76..4962e4b 100644 --- a/trap/stage_renderer.py +++ b/trap/stage_renderer.py @@ -3,6 +3,7 @@ from argparse import ArgumentParser from collections import deque import math +import re from typing import List import numpy as np import pyglet @@ -11,7 +12,7 @@ import zmq from trap.lines import RenderableLayers, message_to_layers from trap.node import Node -BG_COLOR = (0,0,0) +BG_COLOR = (0,0,255) class StageRenderer(Node): def setup(self): # self.prediction_sock = self.sub(self.config.zmq_prediction_addr) @@ -49,6 +50,9 @@ class StageRenderer(Node): # self.window.set_size(1080, 1920) window_size = self.window.get_size() + + padding = 40 + print(window_size) self.window.set_handler('on_draw', self.on_draw) # self.window.set_handler('on_close', self.on_close) @@ -68,14 +72,14 @@ class StageRenderer(Node): self.text = pyglet.text.document.FormattedDocument("") self.text_batch = pyglet.graphics.Batch() self.text_layout = pyglet.text.layout.TextLayout( - self.text, 20, 350, - width=self.window.get_size()[1], - height=self.window.get_size()[0] // 3, + self.text, padding, (self.window.get_size()[0]-padding*2) // 2 - 100, + width=self.window.get_size()[1] - 2*padding, + height=(self.window.get_size()[0] - padding) // 2, multiline=True, wrap_lines=False, batch=self.text_batch) - max_len = 30 + max_len = 31 self.log_msgs = deque([], maxlen=max_len) - self.log_msgs.extend(["..."] * max_len) + self.log_msgs.extend(["-"] * max_len) translate = (10,-400) @@ -86,7 +90,6 @@ class StageRenderer(Node): max_y = 14.3 scale = min(smallest_dimension / max_x, smallest_dimension/max_y) - padding = 40 self.logger.info(f"Use {scale=}") @@ -110,6 +113,8 @@ class StageRenderer(Node): clear_area = img_y self.clear_transparent = pyglet.shapes.Rectangle(0, window_size[1]-clear_area, window_size[0], clear_area, color=(*BG_COLOR,255//70)) self.clear_fully= pyglet.shapes.Rectangle(0, 0, window_size[0], window_size[1]-clear_area, color=(*BG_COLOR,255)) + + self.window.clear() def check_running(self, dt): @@ -178,25 +183,23 @@ class StageRenderer(Node): color = (p2.color.as_array()*255).astype(int) if i < len(self.lines): - print('reuse') shape = self.lines[i] shape.x = pos1[0] shape.y = pos1[1] shape.x2 = pos2[0] shape.y2 = pos2[1] shape.color = color + else: + self.lines.append(pyglet.shapes.Line(pos1[0], pos1[1], + pos2[0], + pos2[1], + 3, + color, + batch=self.lines_batch)) - self.lines.append(pyglet.shapes.Line(pos1[0], pos1[1], - pos2[0], - pos2[1], - 3, - color, - batch=self.lines_batch)) - - print(len(self.lines), i) + too_many = len(self.lines) - 1 - i if too_many > 0: - print('del', too_many) for j in reversed(range(i, i+too_many)): self.lines[i].delete() del self.lines[i] @@ -210,20 +213,38 @@ class StageRenderer(Node): font_size=18, color=(255, 255, 255, 255), )) + + + colorsmap = { + 'ANOMALOUS': (255, 0, 0, 255), + 'LOITERING': (255, 255, 0, 255), + 'DETECTED': (255, 0, 255, 255), + 'SUBSTANTIAL': (255, 0, 255, 255), + 'LOST': (0, 0, 0, 255), + } + + matchtext = "".join(self.log_msgs) # find no newlines + for state,color in colorsmap.items(): + for match in re.finditer(state, matchtext): + self.text.set_style(match.start(), match.end(), dict( + color=color + )) + + def on_draw(self): self.receive(.1) - self.window.clear() - # self.clear_transparent.color = (*BG_COLOR, int(255*self.get_setting('stagerenderer.fade', .27))) - # self.clear_transparent.draw() - # self.clear_fully.draw() + # self.window.clear() + self.clear_transparent.color = (*BG_COLOR, int(3)) + self.clear_transparent.draw() + self.clear_fully.draw() self.fps_display.draw() - # self.bg_sprite.draw() + self.bg_sprite.draw() - # self.lines_batch.draw() - # self.text_batch.draw() + self.lines_batch.draw() + self.text_batch.draw() @classmethod @@ -248,8 +269,8 @@ class StageRenderer(Node): type=str, default="SETTINGS/2025-11-dortmund/space/floorplan.png") render_parser.add_argument('--monitor', - help='Specify a screen on which to output (eg. HDMI-1)', + help='Specify a screen on which to output (eg. HDMI-0)', type=str, - default="HDMI-1") + default="HDMI-0") return render_parser diff --git a/trap/track_writer.py b/trap/track_writer.py index 6d43c6c..2616ad6 100644 --- a/trap/track_writer.py +++ b/trap/track_writer.py @@ -6,18 +6,20 @@ from pathlib import Path import zmq +from trap.base import Track from trap.frame_emitter import Frame from trap.node import Node -from trap.tracker import TrainingDataWriter +from trap.tracker import TrainingDataWriter, TrainingTrackWriter class TrackWriter(Node): def setup(self): - self.track_sock = self.sub(self.config.zmq_trajectory_addr) + self.track_sock = self.sub(self.config.zmq_lost_addr) + self.log_sock = self.push(self.config.zmq_log_addr) def run(self): - with TrainingDataWriter(self.config.output_dir) as writer: + with TrainingTrackWriter(self.config.output_dir) as writer: try: while self.run_loop(): zmq_ev = self.track_sock.poll(timeout=1000) @@ -26,10 +28,20 @@ class TrackWriter(Node): continue try: - frame: Frame = self.track_sock.recv_pyobj() - writer.add(frame, frame.tracks.values()) + track: Track = self.track_sock.recv_pyobj() + + if len(track.history) < 20: + self.logger.debug(f"ignore short track {len(track.history)}") + continue + + writer.add(track) - self.logger.debug(f"write frame {frame.time:.3f} with {len(frame.tracks)} tracks") + self.logger.info(f"Added track {track.track_id}") + + try: + self.log_sock.send_string(f"Added track {track.track_id} to dataset, {len(track.history)} datapoints", zmq.NOBLOCK) + except Exception as e: + self.logger.warning("Not sent the message, broken socket?") except zmq.ZMQError as e: @@ -44,10 +56,14 @@ class TrackWriter(Node): @classmethod def arg_parser(cls): argparser = ArgumentParser() - argparser.add_argument('--zmq-trajectory-addr', + argparser.add_argument('--zmq-log-addr', + help='Manually specity communication addr for the log messages', + type=str, + default="tcp://0.0.0.0:99188") + argparser.add_argument('--zmq-lost-addr', help='Manually specity communication addr for the trajectory messages', type=str, - default="ipc:///tmp/feeds_traj") + default="ipc:///tmp/feeds_lost") argparser.add_argument("--output-dir", help="Directory to save the video in", required=True, diff --git a/trap/tracker.py b/trap/tracker.py index e1cd680..2c1158b 100644 --- a/trap/tracker.py +++ b/trap/tracker.py @@ -127,14 +127,37 @@ class TrackReader: def __init__(self, path: Path, fps: int, include_blacklisted = False, exclude_whitelisted = False): self.blacklist_file = path / "blacklist.jsonl" self.whitelist_file = path / "whitelist.jsonl" # for skipping - self.tracks_file = path / "tracks.pkl" + # self.tracks_file = path / "tracks.pkl" + self.tracks_files = path.glob('tracks*.pkl') # with self.tracks_file.open('r') as fp: # tracks_dict: dict = json.load(fp) - - with self.tracks_file.open('rb') as fp: - tracks: dict = pickle.load(fp) + + tracks: Dict[str, Track] = {} + for tracks_file in self.tracks_files: + logger.info(f"Read {tracks_file}") + with tracks_file.open('rb') as fp: + while True: + # multiple tracks can be pickled separately + try: + trackset: Dict[str, Track] = pickle.load(fp) + for track_id, track in trackset.items(): + if len(tracks) < 1: + max_item = 0 + else: + max_item = max([int(t) for t in tracks.keys()]) + if int(track.track_id) < max_item: + track_id = str(max_item+1) + else: + track_id = track.track_id + + track.track_id = track_id + tracks[track.track_id] = track + except EOFError: + break + + if self.blacklist_file.exists(): with jsonlines.open(self.blacklist_file, 'r') as reader: @@ -255,8 +278,50 @@ class TrainingDataWriter: self.training_fp.close() rewrite_raw_track_files(self.path) + + +class TrainingTrackWriter: + """ + Supersedes TrainingDataWriter, by writing full tracks""" + def __init__(self, training_path: Optional[Path]): + if training_path is None: + self.path = None + return - + if not isinstance(training_path, Path): + raise ValueError("save-for-training should be a path") + if not training_path.exists(): + logger.info(f"Making path for training data: {training_path}") + training_path.mkdir(parents=True, exist_ok=False) + else: + logger.warning(f"Path for training-data exists: {training_path}. Continuing assuming that's ok.") + + self.path = training_path + + def __enter__(self): + if self.path: + d = datetime.now().isoformat(timespec="minutes") + self.training_fp = open(self.path / f'tracks-{d}.pcl', 'wb') + logger.debug(f"Writing tracker data to {self.training_fp.name}") + # following https://github.com/StanfordASL/Trajectron-plus-plus/blob/master/experiments/pedestrians/process_data.py + # self.csv = csv.DictWriter(self.training_fp, fieldnames=FIELDNAMES, delimiter='\t', quoting=csv.QUOTE_NONE) + self.count = 0 + return self + + def add(self, track: Track): + self.count += 1; + pickle.dump(track, self.training_fp) + + + def __exit__(self, exc_type, exc_value, exc_tb): + # ... ignore exception (type, value, traceback) + if not self.path: + return + + self.training_fp.close() + # rewrite_raw_track_files(self.path) + + def rewrite_raw_track_files(path: Path): source_files = list(sorted(path.glob("*.txt"))) # we loop twice, so need a list instead of generator