Initial commit: step2urdf tool with handtuned JSON import.
Includes FastAPI backend, vendored step2urdf frontend, and A7 handtuned arm JSON for URDF generation.
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from app.models import LinkDef, RobotDraft
|
||||
from app.services.a7_gold import A7_LINK_ORDER, enforce_a7_gold_kinematics, gold_joint_defs
|
||||
|
||||
|
||||
def _norm(name: str) -> str:
|
||||
return name.strip()
|
||||
|
||||
|
||||
def group_links_a7(product_names: list[str], robot_name: str = "ARM7_urdf") -> RobotDraft:
|
||||
"""ARM7 gold kinematics; part_names filled later (Solid_N clustered on client)."""
|
||||
names = [_norm(n) for n in product_names if _norm(n)]
|
||||
# Spread Solid_* across gold links by index so apply has a starting bind.
|
||||
links = [LinkDef(name=n, part_names=[]) for n in A7_LINK_ORDER]
|
||||
solids = [n for n in names if n.lower().startswith("solid")]
|
||||
other = [n for n in names if not n.lower().startswith("solid")]
|
||||
if solids:
|
||||
n_link = len(links)
|
||||
for i, sn in enumerate(solids):
|
||||
links[min(i * n_link // max(len(solids), 1), n_link - 1)].part_names.append(sn)
|
||||
if other:
|
||||
links[0].part_names.extend(other)
|
||||
|
||||
draft = RobotDraft(
|
||||
name=robot_name or "ARM7_urdf",
|
||||
profile="a7",
|
||||
links=links,
|
||||
joints=gold_joint_defs(),
|
||||
notes=[
|
||||
"A7 profile: joints from ARM7_urdf.urdf gold standard.",
|
||||
"Axes: A1/3/5=[0,0,-1], A2/4/6=[1,0,0], A7=[0,1,0], A8=fixed.",
|
||||
],
|
||||
raw_parts=names,
|
||||
)
|
||||
return enforce_a7_gold_kinematics(draft)
|
||||
|
||||
|
||||
def seed_generic(product_names: list[str], robot_name: str = "robot") -> RobotDraft:
|
||||
names = [_norm(n) for n in product_names if _norm(n)]
|
||||
return RobotDraft(
|
||||
name=robot_name or "robot",
|
||||
profile="generic",
|
||||
links=[LinkDef(name="base_link", part_names=[])],
|
||||
joints=[],
|
||||
notes=["Generic seed; joints come from LLM."],
|
||||
raw_parts=names,
|
||||
)
|
||||
|
||||
|
||||
def apply_profile(profile: str, product_names: list[str], robot_name: str) -> RobotDraft:
|
||||
if profile == "a7":
|
||||
return group_links_a7(product_names, robot_name=robot_name)
|
||||
return seed_generic(product_names, robot_name=robot_name)
|
||||
Reference in New Issue
Block a user