为基础示例接入按设备 ID 选择的力标定
让使用者从本地目录选标定并看见实际单位。短片回放及相关测试通过。
This commit is contained in:
+2
-1
@@ -31,6 +31,7 @@ __pycache__/
|
||||
/data/*
|
||||
!/data/sample/
|
||||
!/data/sample/**
|
||||
!/data/calibrations/
|
||||
|
||||
# Generated docs / tooling outputs
|
||||
/docs/.quarto/
|
||||
@@ -49,4 +50,4 @@ __pycache__/
|
||||
/outputs/
|
||||
|
||||
# Agent scratch: one directory per task, see D:\orisys_ws\AGENTS.md
|
||||
.scratch/
|
||||
.scratch/
|
||||
|
||||
@@ -94,13 +94,19 @@ cfg = orisys.export_config("box", "./config/exported_config.json")
|
||||
|
||||
For multiple physical sensors, keep calibration files in a user-selected directory:
|
||||
`<calibration_dir>/<product>/<device_id>.json` (for example,
|
||||
`./calibrations/box/BOX-001.json`). Each file uses the existing calibration JSON
|
||||
`data/calibrations/box/BOX-001.json`). Each file uses the existing calibration JSON
|
||||
format and must contain matching `identity.sensor_type` and `identity.sn`, Newton
|
||||
curves for FN/FX/FY, and a compatible measurement pipeline. Enter the device ID
|
||||
manually until hardware identification is available:
|
||||
|
||||
The source checkout provides `data/calibrations/{box,mini,finger}/` folders; device
|
||||
files placed there are ignored by Git. This location is optional: pass
|
||||
`--calibration-dir data/calibrations`
|
||||
and `--device-id BOX-001` to `examples/basic_pipeline.py` to select a file there.
|
||||
Installed wheels do not create or search this directory automatically.
|
||||
|
||||
```python
|
||||
sensor = orisys.Sensor(0, config_name="box", calibration_dir="./calibrations", device_id="BOX-001")
|
||||
sensor = orisys.Sensor(0, config_name="box", calibration_dir="data/calibrations", device_id="BOX-001")
|
||||
```
|
||||
|
||||
If that ID has no file, the sensor reports raw force; it never falls back to the
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
*
|
||||
!*/
|
||||
!.gitignore
|
||||
!.gitkeep
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -19,6 +19,7 @@ Run:
|
||||
python examples/basic_pipeline.py -v 0 -c mini
|
||||
python examples/basic_pipeline.py -v recording.mp4 -c box
|
||||
python examples/basic_pipeline.py --no-show # headless: print only
|
||||
python examples/basic_pipeline.py -v 0 -c box --calibration-dir data/calibrations --device-id BOX-001
|
||||
|
||||
Keys: 'q' quit, 'r' reset the tracker.
|
||||
"""
|
||||
@@ -44,18 +45,39 @@ def main() -> int:
|
||||
help="camera index or video file path (default: 0)")
|
||||
parser.add_argument("-c", "--config", default="box",
|
||||
help="product config: box, mini, finger, or a config path")
|
||||
parser.add_argument("--cal", default=None,
|
||||
help="force calibration file; omit to use the sensor bundle's own")
|
||||
calibration = parser.add_mutually_exclusive_group()
|
||||
calibration.add_argument("--cal", default=None,
|
||||
help="force calibration file; omit to use the sensor bundle's own")
|
||||
calibration.add_argument("--calibration-dir", default=None,
|
||||
help="root containing <product>/<device-id>.json")
|
||||
parser.add_argument("--device-id", default=None,
|
||||
help="physical sensor ID; required with --calibration-dir")
|
||||
parser.add_argument("--no-show", dest="show", action="store_false",
|
||||
help="do not open the display windows")
|
||||
parser.add_argument("-verbose", action="store_true", help="SDK verbose logs")
|
||||
args = parser.parse_args()
|
||||
if args.calibration_dir is not None and args.device_id is None:
|
||||
parser.error("--calibration-dir requires --device-id")
|
||||
if args.device_id is not None and args.calibration_dir is None and args.cal is None:
|
||||
parser.error("--device-id requires --calibration-dir or --cal")
|
||||
|
||||
# ------------------------------------------------------------------ create the object
|
||||
# That is the whole setup. The source may be a camera index or a video path.
|
||||
source = int(args.video) if args.video.isdigit() else args.video
|
||||
sensor = orisys.Sensor(source, config_name=args.config, cal_path=args.cal,
|
||||
verbose=args.verbose)
|
||||
sensor = orisys.Sensor(
|
||||
source, config_name=args.config, cal_path=args.cal,
|
||||
calibration_dir=args.calibration_dir, device_id=args.device_id,
|
||||
verbose=args.verbose,
|
||||
)
|
||||
fn_unit, fx_unit, fy_unit = sensor.force_units
|
||||
selected = sensor.calibration.source_path if sensor.calibration else None
|
||||
print(f"Force calibration: {selected or 'none'}")
|
||||
print(f"Force units: FN={fn_unit}, FX={fx_unit}, FY={fy_unit}")
|
||||
if sensor.device_calibration_missing:
|
||||
print(
|
||||
f"Warning: no calibration for {args.device_id!r} under "
|
||||
f"{args.calibration_dir}; force is raw."
|
||||
)
|
||||
|
||||
# contact=True runs contact analysis. include=... selects which arrays each snapshot carries;
|
||||
# arrays that are not included are None, so you pay only for what you use.
|
||||
@@ -99,7 +121,7 @@ def main() -> int:
|
||||
if colour is not None:
|
||||
cv2.imshow("depth", colour)
|
||||
|
||||
key = cv2.waitKey(1) & 0xFF
|
||||
key = cv2.waitKey(1) & 0xFF if args.show else -1
|
||||
if key == ord("q"):
|
||||
print("\nExiting.")
|
||||
break
|
||||
@@ -117,4 +139,4 @@ def main() -> int:
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
sys.exit(main())
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
{"from": "docs", "to": "docs", "include": ["get_started.md", "api.md"]},
|
||||
{"from": "examples", "to": "examples", "exclude": ["__pycache__", "*.pyc", "*.pyo"]},
|
||||
{"from": "config", "to": "config", "include": ["box.json", "finger.json", "mini.json"]},
|
||||
{"from": "data/calibrations", "to": "data/calibrations", "include": [
|
||||
".gitignore",
|
||||
"box/.gitkeep",
|
||||
"mini/.gitkeep",
|
||||
"finger/.gitkeep"
|
||||
]},
|
||||
{"from": "sensors", "to": "sensors", "include": [
|
||||
"box/sensor.json",
|
||||
"box/force_calibration.json",
|
||||
|
||||
Reference in New Issue
Block a user