initial commit
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
# orisys-sensor-design
|
||||
|
||||
Nominal sensor geometry and Blender authoring for Orisys. This repo is the **design**
|
||||
source of truth. Measured calibration, unroll maps, and shipped runtime bundles live in
|
||||
`orisys-sdk` and compiled `.oryscene` packages live in `orisys-app`.
|
||||
|
||||
For the full long-term workflow see `sensor-design-workflow.md` in the workspace root.
|
||||
This repository intentionally implements a **minimal v1** for a small team.
|
||||
|
||||
## Two buckets (daily work)
|
||||
|
||||
| Bucket | Where | Contents |
|
||||
|--------|-------|----------|
|
||||
| **Design** | this repo | `.blend`, nominal export, release manifest |
|
||||
| **Runtime** | `orisys-sdk` / `orisys-app` | measured cal, unroll map, wheel/App assets, `.oryscene` |
|
||||
|
||||
Never copy runtime NPZ files into this repo to “fix” a mismatch. Promote through a
|
||||
manifest + lock file instead.
|
||||
|
||||
## Layout
|
||||
|
||||
```text
|
||||
sensors/finger/
|
||||
├── current.yaml # active revision pointer
|
||||
└── r01/
|
||||
├── design.yaml # units, frames, object names
|
||||
├── source/geometry.blend # LFS: named collections + objects
|
||||
├── profiles/
|
||||
│ ├── compute.yaml # → SDK bundle layout (Studio runtime)
|
||||
│ └── studio.yaml # inputs for orisys-app compile_scene
|
||||
└── golden/ # optional preview + metrics
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Python 3.10+
|
||||
- [Git LFS](https://git-lfs.com/) on every client (`git lfs install`)
|
||||
- Blender version pinned in `blender.lock.json` (install separately)
|
||||
|
||||
### Finding Blender on Windows
|
||||
|
||||
The CLI looks for Blender in this order:
|
||||
|
||||
1. Env `ORISYS_BLENDER` or `BLENDER_EXE` (absolute path to `blender.exe`)
|
||||
2. `blender` / `blender.exe` on `PATH`
|
||||
3. Auto-scan `%ProgramFiles%\Blender Foundation\Blender *\blender.exe`
|
||||
(prefers `blender.lock.json` version when installed, otherwise newest)
|
||||
4. Optional `"executable"` in `blender.lock.json` (local only; do not commit machine paths)
|
||||
|
||||
```powershell
|
||||
$env:ORISYS_BLENDER = "C:\Program Files\Blender Foundation\Blender 5.0\blender.exe"
|
||||
```
|
||||
|
||||
Convenience launcher (auto-finds Blender for this process, then exports):
|
||||
|
||||
```powershell
|
||||
.\tools\export-compute.bat
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
Install the CLI (editable):
|
||||
|
||||
```powershell
|
||||
cd D:\orisys_ws\orisys-sensor-design
|
||||
python -m pip install -e .
|
||||
```
|
||||
|
||||
Three commands for v1:
|
||||
|
||||
```powershell
|
||||
# 1) Check revision metadata and (optionally) Blender scene conventions
|
||||
orisys-design validate sensors/finger/r01
|
||||
|
||||
# 2) Export nominal geometry for a profile (compute → SDK layout)
|
||||
orisys-design export sensors/finger/r01 --profile compute
|
||||
|
||||
# 3) Write release manifest with file hashes
|
||||
orisys-design manifest sensors/finger/r01
|
||||
```
|
||||
|
||||
Headless Blender export uses a JSON job file (stdlib `json` inside Blender — no
|
||||
PyYAML required). `orisys-design export` writes it automatically from `design.yaml`:
|
||||
|
||||
```powershell
|
||||
orisys-design export sensors/finger/r01 --profile compute
|
||||
# writes build/export/finger/r01/_export_job.json then runs Blender
|
||||
```
|
||||
|
||||
Manual Blender invocation with the same job:
|
||||
|
||||
```powershell
|
||||
blender -b sensors/finger/r01/source/geometry.blend -P blender/scripts/export.py -- `
|
||||
--job D:\orisys_ws\orisys-sensor-design\build\export\finger\r01\_export_job.json
|
||||
```
|
||||
|
||||
Optional flag overrides (`--output`, `--mesh`, `--cam`, `--origin`) win over job values.
|
||||
|
||||
Export output is grouped by revision:
|
||||
|
||||
```text
|
||||
build/export/finger/r01/
|
||||
├── _export_job.json # Blender input, regenerated by export
|
||||
├── manifest.json # release manifest from `orisys-design manifest`
|
||||
└── compute/ # clean SDK-shaped payload
|
||||
├── mesh.npz
|
||||
├── camera_intrinsics.npz
|
||||
└── world_to_cam.npy
|
||||
```
|
||||
|
||||
Collection check:
|
||||
|
||||
```powershell
|
||||
blender -b sensors/finger/r01/source/geometry.blend -P blender/scripts/validate.py -- sensors/finger/r01
|
||||
```
|
||||
|
||||
## Profiles
|
||||
|
||||
- **`compute`** — `sensing_surface` + `cam_sensor` relative to `origin_sensor`. Writes
|
||||
`mesh.npz`, `camera_intrinsics.npz`, `world_to_cam.npy` (here “world” means the
|
||||
sensor frame). Studio and the wheel build consume this tree via `orisys-sdk` →
|
||||
`assets_dir`.
|
||||
- **`studio`** — documents how to compile a `.oryscene` from the **compute** export
|
||||
plus the measured unroll map in SDK. Observation cameras in Studio are derived from
|
||||
mesh bounds; no Blender `cam_viz` is required.
|
||||
|
||||
## Promotion (SDK / App)
|
||||
|
||||
After export:
|
||||
|
||||
1. Tag this repo, e.g. `finger-r01-assets-v1.0.0`.
|
||||
2. Copy or attach the `build/export/finger/r01/compute/` folder to the SDK asset path
|
||||
(or publish as a release artifact).
|
||||
3. Keep `build/export/finger/r01/manifest.json` beside the payload, and update
|
||||
optional `design-lock.json` in `orisys-sdk` with commit + bundle SHA256.
|
||||
4. Run `orisys-app` `compile_scene.py` using the locked compute export + SDK unroll map.
|
||||
|
||||
Example lock file: `examples/design-lock.json`.
|
||||
|
||||
## Conventions
|
||||
|
||||
- **Units**: metres at export boundaries. Author in mm if you like; set
|
||||
`meters_per_source_unit: 0.001` in `design.yaml`.
|
||||
- **Collections**: `FRAMES`, `EXPORT_COMPUTE`, `ASSEMBLY`, `DESIGN_SIM`, `EXCLUDE`.
|
||||
- **Objects**: `origin_sensor`, `sensing_surface`, `cam_sensor`.
|
||||
- **Matrix names** must state direction; exported pose file remains `world_to_cam.npy`
|
||||
for SDK compatibility (sensor frame → camera).
|
||||
- **Git LFS**: `*.blend`, large textures, exported `*.npz` in `build/export/`.
|
||||
|
||||
## Git LFS on Gitea (NAS)
|
||||
|
||||
**Short answer: not difficult.** Gitea has built-in LFS; NAS hosting is common. Plan for
|
||||
extra disk on the NAS volume that holds LFS objects, not just the git bare repos.
|
||||
|
||||
### Server (one-time, ~5 minutes)
|
||||
|
||||
1. **Enable LFS in Gitea** — edit `app.ini` (or Docker env):
|
||||
|
||||
```ini
|
||||
[server]
|
||||
LFS_START_SERVER = true
|
||||
|
||||
[lfs]
|
||||
PATH = /data/git/lfs
|
||||
```
|
||||
|
||||
Docker Compose equivalent:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
- GITEA__server__LFS_START_SERVER=true
|
||||
```
|
||||
|
||||
Point `PATH` at persistent NAS storage (same volume as `/data` is fine).
|
||||
|
||||
2. **Restart Gitea** after changing config.
|
||||
|
||||
3. **Optional**: set `LFS_JWT_SECRET` in Docker/env for stable LFS auth across restarts
|
||||
(generate once, keep in your NAS secrets).
|
||||
|
||||
4. **Reverse proxy**: LFS uploads use HTTP(S) batch API. Ensure your NAS proxy allows
|
||||
large request bodies (nginx `client_max_body_size`, etc.). SSH git push still works
|
||||
for normal objects; LFS file transfer is usually HTTPS unless you enable pure SSH LFS.
|
||||
|
||||
5. **Backup**: include the LFS directory in NAS backup — it is not inside git history.
|
||||
|
||||
Requirements: Git ≥ 2.1.2 on the server (Gitea’s embedded git is enough).
|
||||
|
||||
### Clients (each developer)
|
||||
|
||||
```powershell
|
||||
git lfs install
|
||||
git clone git@your-nas:team/orisys-sensor-design.git
|
||||
cd orisys-sensor-design
|
||||
git lfs pull
|
||||
```
|
||||
|
||||
This repo’s `.gitattributes` already tracks `*.blend` and large binaries. After
|
||||
`git lfs track`, always commit `.gitattributes`.
|
||||
|
||||
### Typical pitfalls
|
||||
|
||||
| Issue | Fix |
|
||||
|-------|-----|
|
||||
| Push succeeds but `.blend` is a tiny pointer file | Run `git lfs install` before commit; re-add file |
|
||||
| LFS upload 413 / timeout | Increase proxy body size and Gitea `[server] LFS_HTTP_TIMEOUT` if needed |
|
||||
| Wrong permissions on NAS volume | Match container `USER_UID` / `USER_GID` to volume owner |
|
||||
| Repo already has large blobs in history | Do not rewrite history casually; use `git lfs migrate` only with team agreement |
|
||||
|
||||
Pure SSH LFS (`LFS_ALLOW_PURE_SSH`) is optional and still has client quirks; HTTPS LFS
|
||||
behind your NAS reverse proxy is the path of least resistance.
|
||||
|
||||
## Phase plan
|
||||
|
||||
| Phase | Goal |
|
||||
|-------|------|
|
||||
| **A** (now) | Repo + LFS + r01 + headless compute export |
|
||||
| **B** | Lock file in SDK/App + CI reproduces export hashes |
|
||||
| **C** (later) | Markers, camera metrics, simulation datasets |
|
||||
Reference in New Issue
Block a user