examples/gui/ is a full Qt + open3d application (30 modules, 4,815 lines) rather than an example, and its proper home is the orisys-studio application. The move is planned but not started, so this records the plan rather than performing any of it. What the plan establishes, so the work does not have to be re-derived: - src/orisys/ imports no gui/viz/examples module, verified by AST rather than grep. The dependency is one-way, so the GUI can leave without a library change. The single apparent hit is `from .pipeline import ...` in src/orisys/__init__.py, which is the SDK's own module. - examples/viz/ is shared and cannot follow the GUI wholesale: it mixes open3d renderers with toolkit-independent helpers that examples/pipeline/service.py and tests/test_contact_arrow_scale.py depend on. It has to be split. - The real coupling is inverted and lives in the tests: tests/test_qt_viewer_backend.py imports examples/gui, and tests/conftest.py deliberately puts examples/ ahead of build/ because both define a package named `gui`. Removing the GUI means re-deriving that guard, not deleting it blindly. - UVMeshViewer and friends are in src/orisys/finger/__init__.__all__, so removing them is a breaking change to a released API and needs a deprecation release first. It must not be folded into a code move. - The `examples/` directory must keep existing in the packaged layout even after gui/ leaves it: src/orisys/configs.py anchors its run-root detection on a sibling examples/ folder. Also updates examples/README.md to say "lives here for now" instead of "is moving out", so nothing reads as work in progress. The GUI itself is untouched, and the only guidance offered is that new SDK work should not build on it.
3.8 KiB
Examples
Runnable demos live at the examples/ root. Shared helpers stay in pipeline/, viz/, and
gui/. Run commands from the repository root.
Start here
Both recommended examples create one object, then read a frame at a time. Everything else -
camera reading, stitching, preprocessing, the optical-flow and force stages - happens inside
StreamPipeline, and each frame arrives as one FrameSnapshot. There is no stage sequence to
remember and no tuple to unpack, and no backend setting to tune.
| Product | Entry | Default config |
|---|---|---|
| ORY-BOX | basic_pipeline.py |
box |
| ORY-MINI | basic_pipeline.py -c mini |
mini |
| ORY-FINGER | finger_pipeline.py |
finger |
# ORY-BOX / ORY-MINI
sensor = orisys.Sensor(0, config_name="box")
with orisys.StreamPipeline(sensor, sensor.get_img, contact=True) as pipe:
while (snap := pipe.wait()) is not None:
print(snap.normal_force, snap.shear_x, snap.shear_y)
# ORY-FINGER - the runtime owns camera, Blender export, unroll map and valid mask
runtime = FingerRuntime.open(config="finger", video=0)
with runtime.pipeline(contact=True) as pipe:
while (snap := pipe.wait()) is not None:
print(snap.normal_force, snap.shear_x, snap.shear_y)
contact=True runs contact analysis; include=(...) chooses which arrays each snapshot carries
(image, flow, vnormal, vshear, depth, centroid, contour). Arrays you do not include
are None, so you pay only for what you use. pipe.reset() resets the tracker safely from your
loop; snap.image_size_raw reports the capture resolution before UV unroll or resize.
Typical usage
python examples/basic_pipeline.py -v 0 -c box # first camera, ORY-BOX
python examples/basic_pipeline.py -v 0 -c mini # ORY-MINI
python examples/basic_pipeline.py -v recording.mp4 -c box
python examples/basic_pipeline.py --no-show # headless: print only
python examples/finger_pipeline.py --camera_id 0 --config finger
python examples/finger_pipeline.py --video data/dd02-0703/1.mp4
Keys in both: q quits, r resets the tracker.
The manual form, for when you need the stages
examples/archive/ holds the previous versions of these two examples. They call the stages by
hand:
sensor.get_img()
sensor.compute_deformation()
sensor.compute_contact()
fps, flow, vnormal, img, ... = sensor.read_info( ... ) # positional, 13 elements
That path is still supported and still correct - it is the right choice if you are implementing your own scheduling. It is no longer the recommended starting point, and the archived files carry a header explaining the difference. They are kept so that code copied from them keeps working.
Other root examples
multi_stream.py- several sensors at once, usingStreamPipelinewithStreamRecordertwo_sensor_pipeline.py- two-sensor multiprocessing demo, manual stagingplot_data.py- single-sensor OpenCV views plus PyQtGraph force chartsfinger_pipeline_3dview.py- the Qt/open3d dashboard; see the note below
Requirements
- SDK installed from the repository root:
pip install -e . - a camera index or a test video path
- matching config names under
./config/or the packagedorisys/configs/
Qt / PyQtGraph examples additionally need pip install -e ".[gui]".
The GUI lives here for now
examples/gui/ - the 2D viewer, the 3D dashboard and their widgets - is a full Qt + open3d
application rather than an example, and its proper home is the orisys-studio application.
That move is planned but not started; finger_pipeline_3dview.py and examples/gui/ work
exactly as before. The plan, including the coupling that makes it non-trivial, is in
docs/plan-gui-extraction.md.
The practical guidance is only that new SDK work should not build on examples/gui/.