Skip to content

Commit 8ea53c8

Browse files
author
Michał Fąferek
committed
feat(mosaico_integration): add fleet comparison cells to notebook
Two new cells at the end of the notebook that pull LaserScan stats from both LIDAR_SIM sequences and plot noise vs drift side by side.
1 parent 222d947 commit 8ea53c8

1 file changed

Lines changed: 12 additions & 0 deletions

File tree

demos/mosaico_integration/notebooks/mosaico_demo.ipynb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,11 @@
239239
" )"
240240
]
241241
},
242+
{
243+
"cell_type": "markdown",
244+
"source": "## 7. Fleet comparison: noise vs drift\n\nThe fleet variant injects two different LiDAR faults, both reported as `LIDAR_SIM`. Metadata alone cannot tell them apart. Pulling the actual scan statistics from Mosaico reveals two distinct failure signatures.\n\nSkip this section if you only ran the single-robot variant (it needs 2+ LIDAR_SIM sequences).",
245+
"metadata": {}
246+
},
242247
{
243248
"cell_type": "code",
244249
"execution_count": null,
@@ -247,6 +252,13 @@
247252
"source": [
248253
"client.close()"
249254
]
255+
},
256+
{
257+
"cell_type": "code",
258+
"source": "if len(lidar_sequences) >= 2:\n def _pull_scan_stats(seq_name):\n _sh = client.sequence_handler(seq_name)\n _topic = _sh.get_topic_handler(\"/sensors/scan\")\n recs = []\n for item in _topic.get_data_streamer():\n arr = np.array(item.data.ranges, dtype=float)\n fin = arr[np.isfinite(arr)]\n recs.append({\n \"timestamp_ns\": item.timestamp_ns,\n \"range_mean\": float(fin.mean()) if fin.size else math.nan,\n \"range_std\": float(fin.std()) if fin.size else math.nan,\n })\n df = pd.DataFrame(recs)\n df[\"t_s\"] = (df[\"timestamp_ns\"] - df[\"timestamp_ns\"].iloc[0]) / 1e9\n return df\n\n seq_a, seq_b = lidar_sequences[0], lidar_sequences[1]\n df_a = _pull_scan_stats(seq_a)\n df_b = _pull_scan_stats(seq_b)\n\n fig, axes = plt.subplots(2, 2, figsize=(14, 6), sharex=\"col\")\n\n axes[0, 0].plot(df_a[\"t_s\"], df_a[\"range_std\"], color=\"crimson\", lw=1.4)\n axes[0, 0].set_ylabel(\"range std [m]\")\n axes[0, 0].set_title(seq_a, fontsize=9)\n axes[0, 0].grid(alpha=0.3)\n\n axes[0, 1].plot(df_b[\"t_s\"], df_b[\"range_std\"], color=\"crimson\", lw=1.4)\n axes[0, 1].set_title(seq_b, fontsize=9)\n axes[0, 1].grid(alpha=0.3)\n\n axes[1, 0].plot(df_a[\"t_s\"], df_a[\"range_mean\"], color=\"steelblue\", lw=1.4)\n axes[1, 0].set_ylabel(\"range mean [m]\")\n axes[1, 0].set_xlabel(\"time [s]\")\n axes[1, 0].grid(alpha=0.3)\n\n axes[1, 1].plot(df_b[\"t_s\"], df_b[\"range_mean\"], color=\"steelblue\", lw=1.4)\n axes[1, 1].set_xlabel(\"time [s]\")\n axes[1, 1].grid(alpha=0.3)\n\n fig.suptitle(\n \"Same fault_code (LIDAR_SIM), different root cause\",\n fontsize=13, fontweight=\"bold\",\n )\n plt.tight_layout()\n plt.savefig(\"../docs/fleet_comparison.png\", dpi=120, bbox_inches=\"tight\")\n plt.show()\n print(f\"Left: {seq_a}\\nRight: {seq_b}\")\nelse:\n print(f\"Only {len(lidar_sequences)} LIDAR_SIM sequence(s). Run the fleet variant for comparison.\")",
259+
"metadata": {},
260+
"execution_count": null,
261+
"outputs": []
250262
}
251263
],
252264
"metadata": {

0 commit comments

Comments
 (0)