saltybot_uwb_logger_msgs (new package):
- AccuracyReport.msg: n_samples, mean/bias/std (x,y,2D), CEP50, CEP95,
RMSE, max_error, per-anchor range stats, test_id, duration_s
- StartAccuracyTest.srv: request (truth_x/y_m, n_samples, timeout_s,
test_id) → response (success, message, test_id)
saltybot_uwb_logger (new package):
- accuracy_stats.py: compute_stats() + RangeAccum — pure numpy, no ROS2
CEP50/CEP95 = 50th/95th percentile of 2-D error; bias, std, RMSE, max
- logger_node.py: /uwb_logger ROS2 node
Subscribes:
/saltybot/pose/fused → fused_pose_<DATE>.csv (ts, x, y, heading)
/saltybot/uwb/pose → uwb_pose_<DATE>.csv (ts, x, y)
/uwb/ranges → uwb_ranges_<DATE>.csv (ts, anchor_id, range_m,
raw_mm, rssi, tag_id)
Service /saltybot/uwb/start_accuracy_test:
Collects N fused-pose samples at known (truth_x, truth_y) in background
thread. On completion or timeout: publishes AccuracyReport on
/saltybot/uwb/accuracy_report + writes accuracy_<test_id>.json.
Per-anchor range stats included. CSV flushed every 5 s.
Tests: 16/16 passing (test/test_accuracy_stats.py, no ROS2/hardware)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
30 lines
871 B
Python
30 lines
871 B
Python
import os
|
|
from glob import glob
|
|
from setuptools import setup
|
|
|
|
package_name = "saltybot_uwb_logger"
|
|
|
|
setup(
|
|
name=package_name,
|
|
version="0.1.0",
|
|
packages=[package_name],
|
|
data_files=[
|
|
("share/ament_index/resource_index/packages",
|
|
[f"resource/{package_name}"]),
|
|
(f"share/{package_name}", ["package.xml"]),
|
|
(os.path.join("share", package_name, "launch"), glob("launch/*.py")),
|
|
(os.path.join("share", package_name, "config"), glob("config/*.yaml")),
|
|
],
|
|
install_requires=["setuptools"],
|
|
zip_safe=True,
|
|
maintainer="sl-uwb",
|
|
maintainer_email="sl-uwb@saltylab.local",
|
|
description="UWB position logger and accuracy analyzer (Issue #634)",
|
|
license="Apache-2.0",
|
|
entry_points={
|
|
"console_scripts": [
|
|
"uwb_logger = saltybot_uwb_logger.logger_node:main",
|
|
],
|
|
},
|
|
)
|