Сортировочная ячейка Isaac Sim: CV-пайплайн и меши товаров
Замкнутый контур "поток -> CV -> механика": товары идут по конвейеру с шагом 700 мм, класс определяется стереопайплайном во время движения, пушер и плуг реагируют физически. Состав: * control_test/ - ячейка и CV. run_sorting_cv.py + cv_worker.py (два процесса, потому что torch внутри Isaac роняет сцену), cell.py (физика лент, плуга, пушера), measure_plane.py (замер габаритов), README.md и .memory.md с замерами, проблемами и ловушками * robozon_sorter/ - модули симуляции, scripts/ - утилиты, scene/ - сцены * assets/ - меши товаров, плуг, объекты Objaverse Бейзлайн CV: DEFOM-Stereo vitl, вход 480, iters 24, кроп зоны осмотра, без сегментации. На потоке 700 мм - классы 8/9, габариты MAE 32.8 мм, 469 мс на товар при такте 700 мс. Веса моделей (4.5 ГБ) и пропсы конвейера NVIDIA (274 МБ) не включены - источники и команды скачивания в MODELS.md. Выход прогонов (captures/, runtime/) не включён: воспроизводится. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
"""Вернуть перспективу вьюпорта на обзор ячейки.
|
||||
|
||||
Сдвинута оказалась только служебная камера /OmniverseKit_Persp - она уехала в
|
||||
(-8.96, -5.49, -6.70), то есть ПОД пол, и смотрела снизу. Шесть стереокамер стенда в
|
||||
/RigRS не тронуты (0.0 мм, 0.00°), их править нечего - а именно они участвуют в прогонах.
|
||||
|
||||
Перспектива вьюпорта в файл не пишется и на физику с замерами не влияет: это только то,
|
||||
что видит человек. Поэтому здесь она ставится по фактическому габариту ячейки, а не по
|
||||
запомненному числу - сцена менялась, и старая точка могла бы снова смотреть мимо.
|
||||
"""
|
||||
import sys
|
||||
REPO = "/home/dasha/robozon-sorter"
|
||||
if REPO not in sys.path:
|
||||
sys.path.insert(0, REPO)
|
||||
|
||||
import omni.usd
|
||||
import isaacsim.core.experimental.utils.app as app_utils
|
||||
from isaacsim.core.rendering_manager import ViewportManager
|
||||
from pxr import Usd, UsdGeom, Gf
|
||||
|
||||
stage = omni.usd.get_context().get_stage()
|
||||
bb = UsdGeom.BBoxCache(Usd.TimeCode.Default(), [UsdGeom.Tokens.default_, UsdGeom.Tokens.render])
|
||||
|
||||
# габарит по дорожкам и плугу - то, на что осмысленно смотреть
|
||||
lo = Gf.Vec3d(1e9, 1e9, 1e9); hi = Gf.Vec3d(-1e9, -1e9, -1e9)
|
||||
for p in stage.Traverse():
|
||||
n = p.GetName()
|
||||
if not (n.startswith("ConveyorTrack") or n == "Diverters"):
|
||||
continue
|
||||
r = bb.ComputeWorldBound(p).ComputeAlignedRange()
|
||||
a, b = r.GetMin(), r.GetMax()
|
||||
for i in range(3):
|
||||
lo[i] = min(lo[i], a[i]); hi[i] = max(hi[i], b[i])
|
||||
ctr = Gf.Vec3d((lo[0]+hi[0])/2, (lo[1]+hi[1])/2, (lo[2]+hi[2])/2)
|
||||
span = max(hi[0]-lo[0], hi[1]-lo[1])
|
||||
print(f"габарит ячейки: x {lo[0]:+.2f}..{hi[0]:+.2f} y {lo[1]:+.2f}..{hi[1]:+.2f} "
|
||||
f"z {lo[2]:+.2f}..{hi[2]:+.2f}")
|
||||
print(f"центр ({ctr[0]:+.2f}, {ctr[1]:+.2f}, {ctr[2]:+.2f}), протяжённость {span:.1f} м")
|
||||
|
||||
# три четверти сверху-сбоку: вся линия в кадре, плуг и пушер видны не с торца
|
||||
eye = Gf.Vec3d(ctr[0] + span * 0.45, ctr[1] - span * 0.65, ctr[2] + span * 0.55)
|
||||
tgt = Gf.Vec3d(ctr[0], ctr[1], 1.60)
|
||||
ViewportManager.set_camera_view("/OmniverseKit_Persp",
|
||||
eye=[eye[0], eye[1], eye[2]],
|
||||
target=[tgt[0], tgt[1], tgt[2]])
|
||||
await app_utils.update_app_async(steps=30)
|
||||
|
||||
cache = UsdGeom.XformCache()
|
||||
t = cache.GetLocalToWorldTransform(stage.GetPrimAtPath("/OmniverseKit_Persp")).ExtractTranslation()
|
||||
print(f"\nперспектива возвращена: ({t[0]:+.2f}, {t[1]:+.2f}, {t[2]:+.2f}) "
|
||||
f"-> смотрит на ({tgt[0]:+.2f}, {tgt[1]:+.2f}, {tgt[2]:+.2f})")
|
||||
print("камеры стенда /RigRS не трогались")
|
||||
Reference in New Issue
Block a user