diff --git a/auto_atom/backend/mjc/mujoco_backend.py b/auto_atom/backend/mjc/mujoco_backend.py index dc2d46b..f05fe5f 100644 --- a/auto_atom/backend/mjc/mujoco_backend.py +++ b/auto_atom/backend/mjc/mujoco_backend.py @@ -1019,34 +1019,29 @@ def _resolve_reference_base_pose( For enum modes the entity's own ``default_pose`` is returned. - For an entity-name reference, the delta-carry algorithm is applied: - ``delta = ref_sampled * ref_default⁻¹``, then ``delta * default_pose`` - so the current entity moves with the referenced entity while - preserving their original spatial relationship. + For an entity-name reference, the sampled pose of the referenced + entity is used as the base directly — so ranges like ``x: [-0.005, + 0.005]`` are interpreted as offsets from the referenced entity's + currently randomized pose, not from this entity's XML default. """ if isinstance(reference, RandomizationReference): return default_pose - # --- Entity-name reference: delta-carry --- - ref_sampled = sampled_poses.get(reference) - # Resolve the reference entity's default pose. - if reference in self._default_object_poses: - ref_default = self._default_object_poses[reference] - elif reference in self._default_operator_eef_poses: - ref_default = self._default_operator_eef_poses[reference] - elif reference in self.object_handlers: - ref_default = self.object_handlers[reference].get_pose() - elif reference in self.operator_handlers: - ref_default = self.operator_handlers[reference].get_end_effector_pose() - else: + known_entity = ( + reference in self._default_object_poses + or reference in self._default_operator_eef_poses + or reference in self.object_handlers + or reference in self.operator_handlers + ) + if not known_entity: raise ValueError( f"Randomization reference '{reference}' is not a known mode " "('relative', 'absolute_world', 'absolute_base') nor an " "existing object/operator name." ) + ref_sampled = sampled_poses.get(reference) if ref_sampled is None: - return default_pose # entity not randomized → no delta - delta = compose_pose(ref_sampled, inverse_pose(ref_default)) - return compose_pose(delta, default_pose) + return default_pose # reference not randomized → fall back + return ref_sampled def _apply_randomization(self, env_mask: np.ndarray) -> None: deps = self._randomization_dependencies() @@ -1445,29 +1440,22 @@ def _resolve_reference_base_pose_for_env( ) -> PoseState: if isinstance(reference, RandomizationReference): return default_pose - ref_sampled = sampled_poses.get(reference) - if reference in self._default_object_poses: - ref_default = self._default_object_poses[reference].select(env_index) - elif reference in self._default_operator_eef_poses: - ref_default = self._default_operator_eef_poses[reference].select(env_index) - elif reference in self.object_handlers: - ref_default = self.object_handlers[reference].get_pose().select(env_index) - elif reference in self.operator_handlers: - ref_default = ( - self.operator_handlers[reference] - .get_end_effector_pose() - .select(env_index) - ) - else: + known_entity = ( + reference in self._default_object_poses + or reference in self._default_operator_eef_poses + or reference in self.object_handlers + or reference in self.operator_handlers + ) + if not known_entity: raise ValueError( f"Randomization reference '{reference}' is not a known mode " "('relative', 'absolute_world', 'absolute_base') nor an existing " "object/operator name." ) + ref_sampled = sampled_poses.get(reference) if ref_sampled is None: return default_pose - delta = compose_pose(ref_sampled, inverse_pose(ref_default)) - return compose_pose(delta, default_pose) + return ref_sampled def _current_pose_for_randomization_key(self, name: str) -> PoseState: rand_range = self.randomization[name] diff --git a/examples/panel_assembly/generated/demo_panel_with_objects.xml b/examples/panel_assembly/generated/demo_panel_with_objects.xml new file mode 100644 index 0000000..c258225 --- /dev/null +++ b/examples/panel_assembly/generated/demo_panel_with_objects.xml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/create_initial_objects.py b/examples/panel_assembly/w1_b1/create_initial_objects.py new file mode 100644 index 0000000..c9ad398 --- /dev/null +++ b/examples/panel_assembly/w1_b1/create_initial_objects.py @@ -0,0 +1,110 @@ +"""One-time script: create the 20 initial switch XMLs in objects/. + +Each switch is a simple 8.6cm x 8.6cm square, 7mm thick. +Colours are placeholder grey — edit objects/*.xml to set final colours. +""" + +from __future__ import annotations + +from pathlib import Path + +OBJECTS_DIR = Path(__file__).parent / "objects" + +# Geometry (metres) +BTN_HALF = 0.043 # 43mm half-width (86mm full) +BTN_FACE_HALF = 0.040 # 40mm half (80mm inner face) +BEZEL_HALF_Z = 0.001 # bezel base half-thickness +BTN_HALF_Z = 0.0035 # button half-thickness (7mm total) + +# Metallic colours: (bezel_rgba, button_rgba, specular, shininess) +COLORS = { + "white": { + "bezel": "0.85 0.85 0.88 1", + "button": "0.95 0.95 0.97 1", + "specular": "0.85", + "shininess": "0.9", + }, + "dark_gray": { + "bezel": "0.15 0.15 0.18 1", + "button": "0.25 0.25 0.28 1", + "specular": "0.75", + "shininess": "0.85", + }, + "gold": { + "bezel": "0.65 0.53 0.15 1", + "button": "0.83 0.69 0.22 1", + "specular": "0.9", + "shininess": "0.95", + }, + "pink": { + "bezel": "0.80 0.50 0.58 1", + "button": "0.95 0.65 0.72 1", + "specular": "0.8", + "shininess": "0.9", + }, + "placeholder": { + "bezel": "0.30 0.30 0.33 1", + "button": "0.60 0.60 0.63 1", + "specular": "0.5", + "shininess": "0.5", + }, +} + +# 20 switches: (class_name, x_mm, y_mm, color) +# 白色: 1-2,4-5,10-11,13-14,18 深灰: 3,7-9,12,15-16 金色: 6,20 粉色: 19 +SWITCHES = [ + ("Switch_Quantity2_07", 349.8, 120.0, "white"), # 1 + ("Switch_Quantity2_08", 233.2, 120.0, "white"), # 2 + ("Switch_Quantity2_09", 116.6, 120.0, "dark_gray"), # 3 + ("Switch_Quantity2_10", 0.0, 120.0, "white"), # 4 + ("Switch_Quantity4_02", -116.6, 120.0, "white"), # 5 + ("Switch_Quantity1_45", -233.2, 120.0, "gold"), # 6 + ("Switch_Quantity1_46", -349.8, 120.0, "dark_gray"), # 7 + ("Toogle_Quantity1_05", 349.8, 0.0, "dark_gray"), # 8 + ("Switch_Quantity4_03", 233.2, 0.0, "dark_gray"), # 9 + ("Switch_Quantity1_47", 116.6, 0.0, "white"), # 10 + ("Switch_Quantity2_11", -116.6, 0.0, "white"), # 11 + ("Switch_Quantity1_48", -233.2, 0.0, "dark_gray"), # 12 + ("Switch_Quantity1_49", -349.8, 0.0, "white"), # 13 + ("Switch_Quantity3_06", 349.8, -120.0, "white"), # 14 + ("Toogle_Quantity2_01", 233.2, -120.0, "dark_gray"), # 15 + ("Toogle_Quantity1_06", 116.6, -120.0, "dark_gray"), # 16 + ("Placeholder_31", 0.0, -120.0, "placeholder"), # 17 + ("Switch_Quantity2_12", -116.6, -120.0, "white"), # 18 + ("Switch_Quantity2_13", -233.2, -120.0, "pink"), # 19 + ("Switch_Quantity4_04", -349.8, -120.0, "gold"), # 20 +] + + +def generate_switch_xml(class_name: str, color: str) -> str: + c = COLORS[color] + sp, sh = c["specular"], c["shininess"] + return f""" + + + + + + + + + + +""" + + +def main() -> None: + OBJECTS_DIR.mkdir(exist_ok=True) + for class_name, x, y, color in SWITCHES: + path = OBJECTS_DIR / f"{class_name}.xml" + path.write_text(generate_switch_xml(class_name, color), encoding="utf-8") + print(f" {path.name} ({color})") + print(f"\nCreated {len(SWITCHES)} switch XMLs in {OBJECTS_DIR}") + + +if __name__ == "__main__": + main() diff --git a/examples/panel_assembly/w1_b1/generate_w1_b1.py b/examples/panel_assembly/w1_b1/generate_w1_b1.py new file mode 100644 index 0000000..2f931fb --- /dev/null +++ b/examples/panel_assembly/w1_b1/generate_w1_b1.py @@ -0,0 +1,195 @@ +"""Generate w1_b1 panel assembly from objects/ XML files. + +Reads the 20 switch XML files from objects/ and assembles them into the +final panel. Edit the XMLs in objects/ directly to customise geometry, +materials, or colours, then re-run this script. + +Creates / overwrites: + - layout_w1_b1.yaml + - w1_b1_panel_base.xml + - generated/w1_b1_panel_assembly.xml +""" + +from __future__ import annotations + +from pathlib import Path +from xml.etree import ElementTree as ET + +BASE_DIR = Path(__file__).parent + +# --------------------------------------------------------------------------- +# 20 switch definitions from Excel w1_b1 +# (class_name, type, x_mm, y_mm, num_buttons, wall_pos) +# --------------------------------------------------------------------------- +SWITCHES = [ + ("Switch_Quantity2_07", "Switch", 349.8, 120.0, 2, (1, 1, 1)), + ("Switch_Quantity2_08", "Switch", 233.2, 120.0, 2, (1, 1, 2)), + ("Switch_Quantity2_09", "Switch", 116.6, 120.0, 2, (1, 1, 3)), + ("Switch_Quantity2_10", "Switch", 0.0, 120.0, 2, (1, 1, 4)), + ("Switch_Quantity4_02", "Switch", -116.6, 120.0, 4, (1, 1, 5)), + ("Switch_Quantity1_45", "Switch", -233.2, 120.0, 1, (1, 1, 6)), + ("Switch_Quantity1_46", "Switch", -349.8, 120.0, 1, (1, 1, 7)), + ("Toogle_Quantity1_05", "Toggle", 349.8, 0.0, 1, (1, 2, 1)), + ("Switch_Quantity4_03", "Switch", 233.2, 0.0, 4, (1, 2, 2)), + ("Switch_Quantity1_47", "Switch", 116.6, 0.0, 1, (1, 2, 3)), + ("Switch_Quantity2_11", "Switch", -116.6, 0.0, 2, (1, 2, 5)), + ("Switch_Quantity1_48", "Switch", -233.2, 0.0, 1, (1, 2, 6)), + ("Switch_Quantity1_49", "Switch", -349.8, 0.0, 1, (1, 2, 7)), + ("Switch_Quantity3_06", "Switch", 349.8, -120.0, 3, (1, 3, 1)), + ("Toogle_Quantity2_01", "Toggle", 233.2, -120.0, 2, (1, 3, 2)), + ("Toogle_Quantity1_06", "Toggle", 116.6, -120.0, 1, (1, 3, 3)), + ("Placeholder_31", "Switch", 0.0, -120.0, 1, (1, 3, 4)), + ("Switch_Quantity2_12", "Switch", -116.6, -120.0, 2, (1, 3, 5)), + ("Switch_Quantity2_13", "Switch", -233.2, -120.0, 2, (1, 3, 6)), + ("Switch_Quantity4_04", "Switch", -349.8, -120.0, 4, (1, 3, 7)), +] + +# Panel backplate half-extents (m) +PANEL_HALF_X = 0.958 +PANEL_HALF_Y = 0.025 +PANEL_HALF_Z = 0.470 + +BASE_POS_Y = 30.0 # mm, placement offset from panel center + + +def parse_switch_xml(xml_path: Path) -> tuple[list[ET.Element], list[ET.Element], str]: + """Parse a switch XML → (materials, geoms, body_name).""" + tree = ET.parse(xml_path) + root = tree.getroot() + materials = list(root.iter("material")) + body = root.find(".//worldbody/body") + geoms = list(body.iter("geom")) if body is not None else [] + body_name = body.get("name", "") if body is not None else "" + return materials, geoms, body_name + + +def generate_layout_yaml() -> str: + lines = [ + "# w1_b1 switch wall layout", + "# 20 switches (various button counts), 3 rows x 7 columns", + "# Geometry defined in objects/*.xml", + "", + "panel:", + " xml: w1_b1_panel_base.xml", + " attach_to_body: panel_mount", + "", + "output_xml: generated/w1_b1_panel_assembly.xml", + "", + "layout:", + " coordinate_scale: 0.001 # mm -> m", + " face_axes: [x, z]", + f" base_pos: [0.0, {BASE_POS_Y}, 0.0]", + " default_quat: [0.7071068, -0.7071068, 0.0, 0.0]", + " remove_root_joints: true", + "", + "placements:", + ] + for idx, (cname, stype, x, y, nbtn, wpos) in enumerate(SWITCHES, 1): + w, r, c = wpos + lines.append(f" # {idx}. {cname} | {stype} | {nbtn} btn | wall {wpos}") + lines.append(f" - xml: objects/{cname}.xml") + lines.append(f" pos: [{x}, {y}]") + lines.append(f" row: {r}") + lines.append(f" col: {c}") + return "\n".join(lines) + "\n" + + +def generate_panel_base_xml() -> str: + return f""" + + + + + + + +""" + + +def generate_assembly_xml() -> str: + coord_scale = 0.001 + base_y = BASE_POS_Y * coord_scale + quat = "0.7071068 -0.7071068 0 0" + objects_dir = BASE_DIR / "objects" + + asset_lines: list[str] = [] + slot_lines: list[str] = [] + + for idx, (cname, stype, x_mm, y_mm, nbtn, wpos) in enumerate(SWITCHES, 1): + xml_path = objects_dir / f"{cname}.xml" + if not xml_path.exists(): + print(f" WARNING: {xml_path.name} not found, skipping #{idx}") + continue + + materials, geoms, body_name = parse_switch_xml(xml_path) + w, r, c = wpos + x_m = x_mm * coord_scale + z_m = y_mm * coord_scale + slot_name = f"panel_slot_r{r}_c{c}" + assembled_body = f"{body_name}_r{r}_c{c}" if body_name else f"{cname}_r{r}_c{c}" + + for mat in materials: + asset_lines.append(f" {ET.tostring(mat, encoding='unicode').strip()}") + + slot_lines.append( + f' ' + ) + slot_lines.append(f' ') + for geom in geoms: + orig = geom.get("name", "") + if orig: + geom.set("name", f"{orig}__{slot_name}") + slot_lines.append( + f" {ET.tostring(geom, encoding='unicode').strip()}" + ) + slot_lines.append(" ") + slot_lines.append(" ") + + return f""" + + +{chr(10).join(asset_lines)} + + + + + +{chr(10).join(slot_lines)} + + +""" + + +def main() -> None: + objects_dir = BASE_DIR / "objects" + if not objects_dir.exists(): + print(f"ERROR: {objects_dir} does not exist.") + return + + (BASE_DIR / "generated").mkdir(exist_ok=True) + + layout_path = BASE_DIR / "layout_w1_b1.yaml" + layout_path.write_text(generate_layout_yaml(), encoding="utf-8") + print(f" Created {layout_path.name}") + + base_path = BASE_DIR / "w1_b1_panel_base.xml" + base_path.write_text(generate_panel_base_xml(), encoding="utf-8") + print(f" Created {base_path.name}") + + assembly_path = BASE_DIR / "generated" / "w1_b1_panel_assembly.xml" + assembly_path.write_text(generate_assembly_xml(), encoding="utf-8") + print(f" Created generated/{assembly_path.name}") + + print(f"\nDone. Assembly built from {len(SWITCHES)} switches in objects/") + + +if __name__ == "__main__": + main() diff --git a/examples/panel_assembly/w1_b1/generated/w1_b1_panel_assembly.xml b/examples/panel_assembly/w1_b1/generated/w1_b1_panel_assembly.xml new file mode 100644 index 0000000..7eb1c2d --- /dev/null +++ b/examples/panel_assembly/w1_b1/generated/w1_b1_panel_assembly.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/layout_w1_b1.yaml b/examples/panel_assembly/w1_b1/layout_w1_b1.yaml new file mode 100644 index 0000000..2a0fa24 --- /dev/null +++ b/examples/panel_assembly/w1_b1/layout_w1_b1.yaml @@ -0,0 +1,118 @@ +# w1_b1 switch wall layout +# 20 switches (various button counts), 3 rows x 7 columns +# Geometry defined in objects/*.xml + +panel: + xml: w1_b1_panel_base.xml + attach_to_body: panel_mount + +output_xml: generated/w1_b1_panel_assembly.xml + +layout: + coordinate_scale: 0.001 # mm -> m + face_axes: [x, z] + base_pos: [0.0, 30.0, 0.0] + default_quat: [0.7071068, -0.7071068, 0.0, 0.0] + remove_root_joints: true + +placements: + # 1. Switch_Quantity2_07 | Switch | 2 btn | wall (1, 1, 1) + - xml: objects/Switch_Quantity2_07.xml + pos: [349.8, 120.0] + row: 1 + col: 1 + # 2. Switch_Quantity2_08 | Switch | 2 btn | wall (1, 1, 2) + - xml: objects/Switch_Quantity2_08.xml + pos: [233.2, 120.0] + row: 1 + col: 2 + # 3. Switch_Quantity2_09 | Switch | 2 btn | wall (1, 1, 3) + - xml: objects/Switch_Quantity2_09.xml + pos: [116.6, 120.0] + row: 1 + col: 3 + # 4. Switch_Quantity2_10 | Switch | 2 btn | wall (1, 1, 4) + - xml: objects/Switch_Quantity2_10.xml + pos: [0.0, 120.0] + row: 1 + col: 4 + # 5. Switch_Quantity4_02 | Switch | 4 btn | wall (1, 1, 5) + - xml: objects/Switch_Quantity4_02.xml + pos: [-116.6, 120.0] + row: 1 + col: 5 + # 6. Switch_Quantity1_45 | Switch | 1 btn | wall (1, 1, 6) + - xml: objects/Switch_Quantity1_45.xml + pos: [-233.2, 120.0] + row: 1 + col: 6 + # 7. Switch_Quantity1_46 | Switch | 1 btn | wall (1, 1, 7) + - xml: objects/Switch_Quantity1_46.xml + pos: [-349.8, 120.0] + row: 1 + col: 7 + # 8. Toogle_Quantity1_05 | Toggle | 1 btn | wall (1, 2, 1) + - xml: objects/Toogle_Quantity1_05.xml + pos: [349.8, 0.0] + row: 2 + col: 1 + # 9. Switch_Quantity4_03 | Switch | 4 btn | wall (1, 2, 2) + - xml: objects/Switch_Quantity4_03.xml + pos: [233.2, 0.0] + row: 2 + col: 2 + # 10. Switch_Quantity1_47 | Switch | 1 btn | wall (1, 2, 3) + - xml: objects/Switch_Quantity1_47.xml + pos: [116.6, 0.0] + row: 2 + col: 3 + # 11. Switch_Quantity2_11 | Switch | 2 btn | wall (1, 2, 5) + - xml: objects/Switch_Quantity2_11.xml + pos: [-116.6, 0.0] + row: 2 + col: 5 + # 12. Switch_Quantity1_48 | Switch | 1 btn | wall (1, 2, 6) + - xml: objects/Switch_Quantity1_48.xml + pos: [-233.2, 0.0] + row: 2 + col: 6 + # 13. Switch_Quantity1_49 | Switch | 1 btn | wall (1, 2, 7) + - xml: objects/Switch_Quantity1_49.xml + pos: [-349.8, 0.0] + row: 2 + col: 7 + # 14. Switch_Quantity3_06 | Switch | 3 btn | wall (1, 3, 1) + - xml: objects/Switch_Quantity3_06.xml + pos: [349.8, -120.0] + row: 3 + col: 1 + # 15. Toogle_Quantity2_01 | Toggle | 2 btn | wall (1, 3, 2) + - xml: objects/Toogle_Quantity2_01.xml + pos: [233.2, -120.0] + row: 3 + col: 2 + # 16. Toogle_Quantity1_06 | Toggle | 1 btn | wall (1, 3, 3) + - xml: objects/Toogle_Quantity1_06.xml + pos: [116.6, -120.0] + row: 3 + col: 3 + # 17. Placeholder_31 | Switch | 1 btn | wall (1, 3, 4) + - xml: objects/Placeholder_31.xml + pos: [0.0, -120.0] + row: 3 + col: 4 + # 18. Switch_Quantity2_12 | Switch | 2 btn | wall (1, 3, 5) + - xml: objects/Switch_Quantity2_12.xml + pos: [-116.6, -120.0] + row: 3 + col: 5 + # 19. Switch_Quantity2_13 | Switch | 2 btn | wall (1, 3, 6) + - xml: objects/Switch_Quantity2_13.xml + pos: [-233.2, -120.0] + row: 3 + col: 6 + # 20. Switch_Quantity4_04 | Switch | 4 btn | wall (1, 3, 7) + - xml: objects/Switch_Quantity4_04.xml + pos: [-349.8, -120.0] + row: 3 + col: 7 diff --git a/examples/panel_assembly/w1_b1/objects/Placeholder_31.xml b/examples/panel_assembly/w1_b1/objects/Placeholder_31.xml new file mode 100644 index 0000000..c247895 --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Placeholder_31.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_45.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_45.xml new file mode 100644 index 0000000..e63f44a --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_45.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_46.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_46.xml new file mode 100644 index 0000000..2e33cff --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_46.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_47.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_47.xml new file mode 100644 index 0000000..4a1f884 --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_47.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_48.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_48.xml new file mode 100644 index 0000000..abd6dda --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_48.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_49.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_49.xml new file mode 100644 index 0000000..0e22a92 --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity1_49.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_07.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_07.xml new file mode 100644 index 0000000..a26aa7f --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_07.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_08.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_08.xml new file mode 100644 index 0000000..7007e35 --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_08.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_09.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_09.xml new file mode 100644 index 0000000..846eedc --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_09.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_10.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_10.xml new file mode 100644 index 0000000..9e68205 --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_10.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_11.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_11.xml new file mode 100644 index 0000000..116762d --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_11.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_12.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_12.xml new file mode 100644 index 0000000..99b8ab2 --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_12.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_13.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_13.xml new file mode 100644 index 0000000..0038b5f --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity2_13.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity3_06.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity3_06.xml new file mode 100644 index 0000000..e510c17 --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity3_06.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity4_02.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity4_02.xml new file mode 100644 index 0000000..8ff721a --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity4_02.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity4_03.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity4_03.xml new file mode 100644 index 0000000..d2e8153 --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity4_03.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Switch_Quantity4_04.xml b/examples/panel_assembly/w1_b1/objects/Switch_Quantity4_04.xml new file mode 100644 index 0000000..6ad09a1 --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Switch_Quantity4_04.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Toogle_Quantity1_05.xml b/examples/panel_assembly/w1_b1/objects/Toogle_Quantity1_05.xml new file mode 100644 index 0000000..1060137 --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Toogle_Quantity1_05.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Toogle_Quantity1_06.xml b/examples/panel_assembly/w1_b1/objects/Toogle_Quantity1_06.xml new file mode 100644 index 0000000..c3623ad --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Toogle_Quantity1_06.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/objects/Toogle_Quantity2_01.xml b/examples/panel_assembly/w1_b1/objects/Toogle_Quantity2_01.xml new file mode 100644 index 0000000..d7c6f01 --- /dev/null +++ b/examples/panel_assembly/w1_b1/objects/Toogle_Quantity2_01.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w1_b1/view_panel.py b/examples/panel_assembly/w1_b1/view_panel.py new file mode 100644 index 0000000..8906109 --- /dev/null +++ b/examples/panel_assembly/w1_b1/view_panel.py @@ -0,0 +1,12 @@ +"""View the w1_b1 panel assembly in MuJoCo interactive viewer.""" + +from pathlib import Path + +import mujoco +import mujoco.viewer + +XML_PATH = Path(__file__).parent / "generated" / "w1_b1_panel_assembly.xml" + +model = mujoco.MjModel.from_xml_path(str(XML_PATH)) +data = mujoco.MjData(model) +mujoco.viewer.launch(model, data) diff --git a/examples/panel_assembly/w1_b1/w1_b1_panel_base.xml b/examples/panel_assembly/w1_b1/w1_b1_panel_base.xml new file mode 100644 index 0000000..e9c8b6a --- /dev/null +++ b/examples/panel_assembly/w1_b1/w1_b1_panel_base.xml @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/create_initial_objects.py b/examples/panel_assembly/w2_b1/create_initial_objects.py new file mode 100644 index 0000000..6064064 --- /dev/null +++ b/examples/panel_assembly/w2_b1/create_initial_objects.py @@ -0,0 +1,109 @@ +"""One-time script: create the initial switch XMLs for w2_b1 in objects/. + +Each switch is 8.6cm x 8.6cm square, 7mm thick, default black metallic. +""" + +from __future__ import annotations + +from pathlib import Path + +OBJECTS_DIR = Path(__file__).parent / "objects" + +# Geometry (metres) +BTN_HALF = 0.043 +BTN_FACE_HALF = 0.040 +BEZEL_HALF_Z = 0.001 +BTN_HALF_Z = 0.0035 + +# Default black metallic +BEZEL_RGBA = "0.05 0.05 0.07 1" +BTN_RGBA = "0.10 0.10 0.13 1" +SPECULAR = "0.7" +SHININESS = "0.8" + +COLORS = { + "white": { + "bezel": "0.85 0.85 0.88 1", + "button": "0.95 0.95 0.97 1", + "specular": "0.85", + "shininess": "0.9", + }, + "dark_gray": { + "bezel": "0.15 0.15 0.18 1", + "button": "0.25 0.25 0.28 1", + "specular": "0.75", + "shininess": "0.85", + }, + "gold": { + "bezel": "0.65 0.53 0.15 1", + "button": "0.83 0.69 0.22 1", + "specular": "0.9", + "shininess": "0.95", + }, + "pink": { + "bezel": "0.80 0.50 0.58 1", + "button": "0.95 0.65 0.72 1", + "specular": "0.8", + "shininess": "0.9", + }, + "placeholder": { + "bezel": "0.30 0.30 0.33 1", + "button": "0.60 0.60 0.63 1", + "specular": "0.5", + "shininess": "0.5", + }, +} + + +# 14 switches with known coordinates from Excel w2_b1 +# (class_name, x_mm, y_mm, wall_pos) +SWITCHES = [ + ("Knob_Quantity1_02", -286.5, 160.0, (2, 1, 10)), + ("Knob_Quantity1_01", -356.5, 160.0, (2, 1, 11)), + ("Toogle_Quantity1_01", 217.5, 50.0, (2, 2, 2)), + ("Toogle_Quantity1_02", 111.5, 50.0, (2, 2, 3)), + ("Toogle_Quantity1_03", -100.5, 50.0, (2, 2, 5)), + ("Toogle_Quantity3_01", -206.5, 50.0, (2, 2, 6)), + ("Switch_Quantity3_03", -312.5, 50.0, (2, 2, 7)), + ("Switch_Quantity1_01", 323.5, -80.0, (2, 3, 1)), + ("Switch_Quantity4_01", 217.5, -80.0, (2, 3, 2)), + ("Switch_Quantity1_03", 111.5, -80.0, (2, 3, 3)), + ("Switch_Quantity2_02", 5.5, -80.0, (2, 3, 4)), + ("Switch_Quantity3_02", -100.5, -80.0, (2, 3, 5)), + ("Switch_Quantity1_05", -206.5, -80.0, (2, 3, 6)), + ("Switch_Quantity1_04", -312.5, -80.0, (2, 3, 7)), +] + + +def generate_switch_xml(class_name: str, color: str) -> str: + c = COLORS[color] + sp, sh = c["specular"], c["shininess"] + return f""" + + + + + + + + + + +""" + + +def main() -> None: + OBJECTS_DIR.mkdir(exist_ok=True) + for class_name, x, y, color in SWITCHES: + path = OBJECTS_DIR / f"{class_name}.xml" + path.write_text(generate_switch_xml(class_name, color), encoding="utf-8") + print(f" {path.name} ({color})") + print(f"\nCreated {len(SWITCHES)} switch XMLs in {OBJECTS_DIR}") + + +if __name__ == "__main__": + main() diff --git a/examples/panel_assembly/w2_b1/generate_w2_b1.py b/examples/panel_assembly/w2_b1/generate_w2_b1.py new file mode 100644 index 0000000..8039d02 --- /dev/null +++ b/examples/panel_assembly/w2_b1/generate_w2_b1.py @@ -0,0 +1,170 @@ +"""Generate w2_b1 panel assembly from objects/ XML files. + +Reads switch XMLs from objects/ and assembles them into the final panel. +Edit objects/*.xml to customise, then re-run this script. +""" + +from __future__ import annotations + +from pathlib import Path +from xml.etree import ElementTree as ET + +BASE_DIR = Path(__file__).parent + +# 14 switches from Excel w2_b1 (positions with known coordinates) +# (class_name, x_mm, y_mm, wall_row, wall_col) +SWITCHES = [ + ("Knob_Quantity1_02", -286.5, 160.0, 1, 10), + ("Knob_Quantity1_01", -356.5, 160.0, 1, 11), + ("Toogle_Quantity1_01", 217.5, 50.0, 2, 2), + ("Toogle_Quantity1_02", 111.5, 50.0, 2, 3), + ("Toogle_Quantity1_03", -100.5, 50.0, 2, 5), + ("Toogle_Quantity3_01", -206.5, 50.0, 2, 6), + ("Switch_Quantity3_03", -312.5, 50.0, 2, 7), + ("Switch_Quantity1_01", 323.5, -80.0, 3, 1), + ("Switch_Quantity4_01", 217.5, -80.0, 3, 2), + ("Switch_Quantity1_03", 111.5, -80.0, 3, 3), + ("Switch_Quantity2_02", 5.5, -80.0, 3, 4), + ("Switch_Quantity3_02", -100.5, -80.0, 3, 5), + ("Switch_Quantity1_05", -206.5, -80.0, 3, 6), + ("Switch_Quantity1_04", -312.5, -80.0, 3, 7), +] + +PANEL_HALF_X = 0.42 +PANEL_HALF_Y = 0.025 +PANEL_HALF_Z = 0.22 +BASE_POS_Y = 30.0 + + +def parse_switch_xml(xml_path: Path) -> tuple[list[ET.Element], list[ET.Element], str]: + tree = ET.parse(xml_path) + root = tree.getroot() + materials = list(root.iter("material")) + body = root.find(".//worldbody/body") + geoms = list(body.iter("geom")) if body is not None else [] + body_name = body.get("name", "") if body is not None else "" + return materials, geoms, body_name + + +def generate_layout_yaml() -> str: + lines = [ + "# w2_b1 switch wall layout", + f"# {len(SWITCHES)} switches", + "", + "panel:", + " xml: w2_b1_panel_base.xml", + " attach_to_body: panel_mount", + "", + "output_xml: generated/w2_b1_panel_assembly.xml", + "", + "layout:", + " coordinate_scale: 0.001", + " face_axes: [x, z]", + f" base_pos: [0.0, {BASE_POS_Y}, 0.0]", + " default_quat: [0.7071068, -0.7071068, 0.0, 0.0]", + " remove_root_joints: true", + "", + "placements:", + ] + for idx, (cname, x, y, r, c) in enumerate(SWITCHES, 1): + lines.append(f" # {idx}. {cname} | wall ({r},{c})") + lines.append(f" - xml: objects/{cname}.xml") + lines.append(f" pos: [{x}, {y}]") + lines.append(f" row: {r}") + lines.append(f" col: {c}") + return "\n".join(lines) + "\n" + + +def generate_panel_base_xml() -> str: + return f""" + + + + + + + +""" + + +def generate_assembly_xml() -> str: + coord_scale = 0.001 + base_y = BASE_POS_Y * coord_scale + quat = "0.7071068 -0.7071068 0 0" + objects_dir = BASE_DIR / "objects" + + asset_lines: list[str] = [] + slot_lines: list[str] = [] + + for cname, x_mm, y_mm, r, c in SWITCHES: + xml_path = objects_dir / f"{cname}.xml" + if not xml_path.exists(): + print(f" WARNING: {xml_path.name} not found, skipping") + continue + materials, geoms, body_name = parse_switch_xml(xml_path) + x_m = x_mm * coord_scale + z_m = y_mm * coord_scale + slot_name = f"panel_slot_r{r}_c{c}" + assembled_body = f"{body_name}_r{r}_c{c}" if body_name else f"{cname}_r{r}_c{c}" + + for mat in materials: + asset_lines.append(f" {ET.tostring(mat, encoding='unicode').strip()}") + + slot_lines.append( + f' ' + ) + slot_lines.append(f' ') + for geom in geoms: + orig = geom.get("name", "") + if orig: + geom.set("name", f"{orig}__{slot_name}") + slot_lines.append( + f" {ET.tostring(geom, encoding='unicode').strip()}" + ) + slot_lines.append(" ") + slot_lines.append(" ") + + return f""" + + +{chr(10).join(asset_lines)} + + + + + +{chr(10).join(slot_lines)} + + +""" + + +def main() -> None: + objects_dir = BASE_DIR / "objects" + if not objects_dir.exists(): + print(f"ERROR: {objects_dir} does not exist.") + return + (BASE_DIR / "generated").mkdir(exist_ok=True) + + (BASE_DIR / "layout_w2_b1.yaml").write_text( + generate_layout_yaml(), encoding="utf-8" + ) + print(" Created layout_w2_b1.yaml") + + (BASE_DIR / "w2_b1_panel_base.xml").write_text( + generate_panel_base_xml(), encoding="utf-8" + ) + print(" Created w2_b1_panel_base.xml") + + (BASE_DIR / "generated" / "w2_b1_panel_assembly.xml").write_text( + generate_assembly_xml(), encoding="utf-8" + ) + print(" Created generated/w2_b1_panel_assembly.xml") + + print(f"\nDone. Assembly built from {len(SWITCHES)} switches.") + + +if __name__ == "__main__": + main() diff --git a/examples/panel_assembly/w2_b1/generated/w2_b1_panel_assembly.xml b/examples/panel_assembly/w2_b1/generated/w2_b1_panel_assembly.xml new file mode 100644 index 0000000..8a127c9 --- /dev/null +++ b/examples/panel_assembly/w2_b1/generated/w2_b1_panel_assembly.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/layout_w2_b1.yaml b/examples/panel_assembly/w2_b1/layout_w2_b1.yaml new file mode 100644 index 0000000..8b2c621 --- /dev/null +++ b/examples/panel_assembly/w2_b1/layout_w2_b1.yaml @@ -0,0 +1,87 @@ +# w2_b1 switch wall layout +# 14 switches + +panel: + xml: w2_b1_panel_base.xml + attach_to_body: panel_mount + +output_xml: generated/w2_b1_panel_assembly.xml + +layout: + coordinate_scale: 0.001 + face_axes: [x, z] + base_pos: [0.0, 30.0, 0.0] + default_quat: [0.7071068, -0.7071068, 0.0, 0.0] + remove_root_joints: true + +placements: + # 1. Knob_Quantity1_02 | wall (1,10) + - xml: objects/Knob_Quantity1_02.xml + pos: [-286.5, 160.0] + row: 1 + col: 10 + # 2. Knob_Quantity1_01 | wall (1,11) + - xml: objects/Knob_Quantity1_01.xml + pos: [-356.5, 160.0] + row: 1 + col: 11 + # 3. Toogle_Quantity1_01 | wall (2,2) + - xml: objects/Toogle_Quantity1_01.xml + pos: [217.5, 50.0] + row: 2 + col: 2 + # 4. Toogle_Quantity1_02 | wall (2,3) + - xml: objects/Toogle_Quantity1_02.xml + pos: [111.5, 50.0] + row: 2 + col: 3 + # 5. Toogle_Quantity1_03 | wall (2,5) + - xml: objects/Toogle_Quantity1_03.xml + pos: [-100.5, 50.0] + row: 2 + col: 5 + # 6. Toogle_Quantity3_01 | wall (2,6) + - xml: objects/Toogle_Quantity3_01.xml + pos: [-206.5, 50.0] + row: 2 + col: 6 + # 7. Switch_Quantity3_03 | wall (2,7) + - xml: objects/Switch_Quantity3_03.xml + pos: [-312.5, 50.0] + row: 2 + col: 7 + # 8. Switch_Quantity1_01 | wall (3,1) + - xml: objects/Switch_Quantity1_01.xml + pos: [323.5, -80.0] + row: 3 + col: 1 + # 9. Switch_Quantity4_01 | wall (3,2) + - xml: objects/Switch_Quantity4_01.xml + pos: [217.5, -80.0] + row: 3 + col: 2 + # 10. Switch_Quantity1_03 | wall (3,3) + - xml: objects/Switch_Quantity1_03.xml + pos: [111.5, -80.0] + row: 3 + col: 3 + # 11. Switch_Quantity2_02 | wall (3,4) + - xml: objects/Switch_Quantity2_02.xml + pos: [5.5, -80.0] + row: 3 + col: 4 + # 12. Switch_Quantity3_02 | wall (3,5) + - xml: objects/Switch_Quantity3_02.xml + pos: [-100.5, -80.0] + row: 3 + col: 5 + # 13. Switch_Quantity1_05 | wall (3,6) + - xml: objects/Switch_Quantity1_05.xml + pos: [-206.5, -80.0] + row: 3 + col: 6 + # 14. Switch_Quantity1_04 | wall (3,7) + - xml: objects/Switch_Quantity1_04.xml + pos: [-312.5, -80.0] + row: 3 + col: 7 diff --git a/examples/panel_assembly/w2_b1/objects/Knob_Quantity1_01.xml b/examples/panel_assembly/w2_b1/objects/Knob_Quantity1_01.xml new file mode 100644 index 0000000..d52aba5 --- /dev/null +++ b/examples/panel_assembly/w2_b1/objects/Knob_Quantity1_01.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/objects/Knob_Quantity1_02.xml b/examples/panel_assembly/w2_b1/objects/Knob_Quantity1_02.xml new file mode 100644 index 0000000..973949c --- /dev/null +++ b/examples/panel_assembly/w2_b1/objects/Knob_Quantity1_02.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/objects/Switch_Quantity1_01.xml b/examples/panel_assembly/w2_b1/objects/Switch_Quantity1_01.xml new file mode 100644 index 0000000..c3492f7 --- /dev/null +++ b/examples/panel_assembly/w2_b1/objects/Switch_Quantity1_01.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/objects/Switch_Quantity1_03.xml b/examples/panel_assembly/w2_b1/objects/Switch_Quantity1_03.xml new file mode 100644 index 0000000..833652e --- /dev/null +++ b/examples/panel_assembly/w2_b1/objects/Switch_Quantity1_03.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/objects/Switch_Quantity1_04.xml b/examples/panel_assembly/w2_b1/objects/Switch_Quantity1_04.xml new file mode 100644 index 0000000..d5cae2a --- /dev/null +++ b/examples/panel_assembly/w2_b1/objects/Switch_Quantity1_04.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/objects/Switch_Quantity1_05.xml b/examples/panel_assembly/w2_b1/objects/Switch_Quantity1_05.xml new file mode 100644 index 0000000..6ef19b2 --- /dev/null +++ b/examples/panel_assembly/w2_b1/objects/Switch_Quantity1_05.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/objects/Switch_Quantity2_02.xml b/examples/panel_assembly/w2_b1/objects/Switch_Quantity2_02.xml new file mode 100644 index 0000000..8f4b99e --- /dev/null +++ b/examples/panel_assembly/w2_b1/objects/Switch_Quantity2_02.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/objects/Switch_Quantity3_02.xml b/examples/panel_assembly/w2_b1/objects/Switch_Quantity3_02.xml new file mode 100644 index 0000000..88d9769 --- /dev/null +++ b/examples/panel_assembly/w2_b1/objects/Switch_Quantity3_02.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/objects/Switch_Quantity3_03.xml b/examples/panel_assembly/w2_b1/objects/Switch_Quantity3_03.xml new file mode 100644 index 0000000..20d2ed7 --- /dev/null +++ b/examples/panel_assembly/w2_b1/objects/Switch_Quantity3_03.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/objects/Switch_Quantity4_01.xml b/examples/panel_assembly/w2_b1/objects/Switch_Quantity4_01.xml new file mode 100644 index 0000000..df0fc14 --- /dev/null +++ b/examples/panel_assembly/w2_b1/objects/Switch_Quantity4_01.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/objects/Toogle_Quantity1_01.xml b/examples/panel_assembly/w2_b1/objects/Toogle_Quantity1_01.xml new file mode 100644 index 0000000..f769cb0 --- /dev/null +++ b/examples/panel_assembly/w2_b1/objects/Toogle_Quantity1_01.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/objects/Toogle_Quantity1_02.xml b/examples/panel_assembly/w2_b1/objects/Toogle_Quantity1_02.xml new file mode 100644 index 0000000..e629b66 --- /dev/null +++ b/examples/panel_assembly/w2_b1/objects/Toogle_Quantity1_02.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/objects/Toogle_Quantity1_03.xml b/examples/panel_assembly/w2_b1/objects/Toogle_Quantity1_03.xml new file mode 100644 index 0000000..2ef5023 --- /dev/null +++ b/examples/panel_assembly/w2_b1/objects/Toogle_Quantity1_03.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/objects/Toogle_Quantity3_01.xml b/examples/panel_assembly/w2_b1/objects/Toogle_Quantity3_01.xml new file mode 100644 index 0000000..0e8d5c8 --- /dev/null +++ b/examples/panel_assembly/w2_b1/objects/Toogle_Quantity3_01.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b1/view_panel.py b/examples/panel_assembly/w2_b1/view_panel.py new file mode 100644 index 0000000..56667b8 --- /dev/null +++ b/examples/panel_assembly/w2_b1/view_panel.py @@ -0,0 +1,11 @@ +"""View the w2_b1 panel assembly in MuJoCo interactive viewer.""" + +from pathlib import Path + +import mujoco +import mujoco.viewer + +XML_PATH = Path(__file__).parent / "generated" / "w2_b1_panel_assembly.xml" +model = mujoco.MjModel.from_xml_path(str(XML_PATH)) +data = mujoco.MjData(model) +mujoco.viewer.launch(model, data) diff --git a/examples/panel_assembly/w2_b1/w2_b1_panel_base.xml b/examples/panel_assembly/w2_b1/w2_b1_panel_base.xml new file mode 100644 index 0000000..32229e0 --- /dev/null +++ b/examples/panel_assembly/w2_b1/w2_b1_panel_base.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/generate_layout_from_excel.py b/examples/panel_assembly/w2_b2/generate_layout_from_excel.py new file mode 100644 index 0000000..17ec46a --- /dev/null +++ b/examples/panel_assembly/w2_b2/generate_layout_from_excel.py @@ -0,0 +1,278 @@ +"""Read the w2_b2 sheet from the panel-info Excel workbook and emit a +panel-assembly YAML that uses the **flat-list** placements format. + +Usage: + python examples/panel_assembly/w2_b2/generate_layout_from_excel.py \ + "C:/Users/10529/Downloads/点按工站面板信息记录.xlsx" + + # With explicit output path: + python examples/panel_assembly/w2_b2/generate_layout_from_excel.py \ + "C:/Users/10529/Downloads/点按工站面板信息记录.xlsx" \ + --output examples/panel_assembly/w2_b2/layout_w2_b2.yaml +""" + +from __future__ import annotations + +import argparse +import math +import re +import warnings +from pathlib import Path +from typing import Any + +import openpyxl + +# ── Excel column indices (1-based) ────────────────────────────────────── +COL_TYPE = 2 # B: Switch / Knob / Stop +COL_SEQ = 3 # C: sequence number (1-37) +COL_QTY = 4 # D: quantity +COL_CLASS = 5 # E: class_name e.g. Switch_Quantity1_06 +COL_BTN_CLS = 6 # F: button_class +COL_COORD = 8 # H: distance-from-centre coordinate +COL_POS = 9 # I: (wall, row, col) e.g. (2,4,1) +COL_NOTES = 11 # K: notes (size, diameter, …) + +# ── Known y-values per wall-row (mm) ─────────────────────────────────── +ROW_Y_MAP: dict[int, float] = { + 4: 120.0, + 5: 0.0, + 6: -120.0, +} + +SHEET_NAME = "w2_b2" +DATA_START_ROW = 3 # first row with actual placement data + + +# ── coordinate parsing ────────────────────────────────────────────────── + + +def _parse_coord(raw: Any, *, fallback_y: float | None) -> tuple[float, float]: + """Parse the H-column value into ``(x, y)`` in millimetres. + + Three representations exist in the workbook: + * A string with a comma – ``"350,120"`` / ``"-70,0"`` / ``"350,-120"`` + * A bare integer whose comma was eaten by Excel's thousands separator – + ``350120`` (should be ``350,120``). + * ``None`` – caller must handle. + """ + if raw is None: + raise ValueError("Coordinate cell is empty.") + + if isinstance(raw, str): + parts = [p.strip() for p in raw.split(",")] + if len(parts) == 2: + return float(parts[0]), float(parts[1]) + raise ValueError(f"Cannot parse coordinate string: {raw!r}") + + # Numeric – likely "x,yyy" eaten by thousands-separator formatting. + value = float(raw) + if fallback_y is not None: + # Recover x by treating the number as string-concatenation of x and y. + y_str = str(int(abs(fallback_y))) # e.g. "120" + val_str = str(int(value)) + if val_str.endswith(y_str) and len(val_str) > len(y_str): + x_str = val_str[: -len(y_str)] + return float(x_str), fallback_y + + # Fallback: truncation-based recovery (works for y = ±120). + x = int(value / 1000) + y = value - x * 1000 + if fallback_y is not None and not math.isclose(y, fallback_y, abs_tol=1.0): + warnings.warn( + f"Recovered y={y} differs from expected y={fallback_y} for raw={raw!r}; " + f"using fallback y.", + stacklevel=2, + ) + y = fallback_y + return float(x), float(y) + + +def _parse_wall_pos(raw: Any) -> tuple[int, int, int] | None: + """Parse ``(wall, row, col)`` from the I-column, e.g. ``'(2,4,1)'``.""" + if raw is None: + return None + text = str(raw).strip().strip("()") + parts = [p.strip() for p in text.split(",")] + if len(parts) != 3: + return None + return int(parts[0]), int(parts[1]), int(parts[2]) + + +# ── main extraction ───────────────────────────────────────────────────── + + +def _extract_placements( + excel_path: str | Path, +) -> list[dict[str, Any]]: + wb = openpyxl.load_workbook(str(excel_path), data_only=True) + ws = wb[SHEET_NAME] + + placements: list[dict[str, Any]] = [] + seen_cols: dict[tuple[int, int], int] = {} # (row, col) → seq for dup detection + + for excel_row in range(DATA_START_ROW, ws.max_row + 1): + seq_raw = ws.cell(row=excel_row, column=COL_SEQ).value + if seq_raw is None: + continue + seq = int(seq_raw) + + # ── type ── + type_raw = ws.cell(row=excel_row, column=COL_TYPE).value + if type_raw is None: + # Auto-correct: rows 37-39 are missing type; assume Switch. + type_name = "Switch" + warnings.warn( + f"seq {seq}: type is empty — auto-corrected to 'Switch'.", + stacklevel=2, + ) + else: + type_name = str(type_raw).strip() + + class_name = ws.cell(row=excel_row, column=COL_CLASS).value + if class_name is None: + # Build a fallback class_name from type + seq. + class_name = f"{type_name}_{seq}" + warnings.warn( + f"seq {seq}: class_name is empty — auto-generated '{class_name}'.", + stacklevel=2, + ) + else: + class_name = str(class_name).strip() + + # ── wall position (row, col) ── + wall_pos = _parse_wall_pos(ws.cell(row=excel_row, column=COL_POS).value) + if wall_pos is None: + warnings.warn( + f"seq {seq}: wall position is empty — skipping.", + stacklevel=2, + ) + continue + _, w_row, w_col = wall_pos + fallback_y = ROW_Y_MAP.get(w_row) + + # ── duplicate (row, col) detection ── + rc_key = (w_row, w_col) + if rc_key in seen_cols: + old_seq = seen_cols[rc_key] + # Auto-correct: assign next available col. + max_col_in_row = max(c for (r, c) in seen_cols if r == w_row) + w_col = max_col_in_row + 1 + warnings.warn( + f"seq {seq}: position ({w_row},{rc_key[1]}) already used by seq {old_seq} " + f"— auto-corrected to ({w_row},{w_col}).", + stacklevel=2, + ) + seen_cols[(w_row, w_col)] = seq + + # ── coordinate ── + coord_raw = ws.cell(row=excel_row, column=COL_COORD).value + if coord_raw is None: + warnings.warn( + f"seq {seq}: coordinate is empty — skipping.", + stacklevel=2, + ) + continue + x, y = _parse_coord(coord_raw, fallback_y=fallback_y) + + # ── notes ── + notes = ws.cell(row=excel_row, column=COL_NOTES).value + notes_str = str(notes).strip() if notes else None + + entry: dict[str, Any] = { + "seq": seq, + "type": type_name, + "class_name": class_name, + "xml": f"objects/{type_name}_{seq}.xml", + "pos": [x, y], + "row": w_row, + "col": w_col, + } + if notes_str: + entry["notes"] = notes_str + + placements.append(entry) + + return placements + + +# ── YAML generation ───────────────────────────────────────────────────── + + +def _format_yaml(placements: list[dict[str, Any]]) -> str: + lines: list[str] = [] + lines.append("# Auto-generated from Excel sheet 'w2_b2'") + lines.append( + "# Re-generate: python examples/panel_assembly/w2_b2/" + "generate_layout_from_excel.py " + ) + lines.append("") + lines.append("panel:") + lines.append(" xml: w2_b2_panel_base.xml") + lines.append(" attach_to_body: panel_mount") + lines.append("") + lines.append("output_xml: generated/w2_b2_panel_assembly.xml") + lines.append("") + lines.append("layout:") + lines.append(" coordinate_scale: 0.001 # mm -> m") + lines.append(" face_axes: [x, z]") + lines.append(" base_pos: [0.0, 30.0, 0.0]") + lines.append(" default_quat: [0.7071068, -0.7071068, 0.0, 0.0]") + lines.append(" remove_root_joints: true") + lines.append("") + lines.append("placements:") + + for p in placements: + seq = p["seq"] + typ = p["type"] + row = p["row"] + col = p["col"] + notes = p.get("notes", "") + comment = f"seq {seq} | {typ} | wall ({row},{col})" + if notes: + comment += f" | {notes}" + lines.append(f" # {comment}") + lines.append(f" - xml: {p['xml']}") + lines.append(f" pos: [{p['pos'][0]}, {p['pos'][1]}]") + lines.append(f" row: {row}") + lines.append(f" col: {col}") + + lines.append("") + return "\n".join(lines) + + +# ── CLI ───────────────────────────────────────────────────────────────── + + +def _build_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + description="Generate w2_b2 panel layout YAML from Excel workbook." + ) + parser.add_argument("excel", type=Path, help="Path to the Excel workbook.") + parser.add_argument( + "--output", + type=Path, + default=None, + help="Output YAML path. Defaults to layout_w2_b2.yaml next to this script.", + ) + return parser + + +def main() -> None: + args = _build_parser().parse_args() + placements = _extract_placements(args.excel) + + output = args.output or (Path(__file__).parent / "layout_w2_b2.yaml") + yaml_text = _format_yaml(placements) + output.write_text(yaml_text, encoding="utf-8") + + print(f"Generated {output} with {len(placements)} placements.") + for p in placements: + print( + f" seq={p['seq']:>2} type={p['type']:<6} " + f"pos=({p['pos'][0]:>7.1f}, {p['pos'][1]:>6.1f}) " + f"row={p['row']} col={p['col']} xml={p['xml']}" + ) + + +if __name__ == "__main__": + main() diff --git a/examples/panel_assembly/w2_b2/generated/w2_b2_panel_assembly.xml b/examples/panel_assembly/w2_b2/generated/w2_b2_panel_assembly.xml new file mode 100644 index 0000000..660b5b5 --- /dev/null +++ b/examples/panel_assembly/w2_b2/generated/w2_b2_panel_assembly.xml @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/layout_w2_b2.yaml b/examples/panel_assembly/w2_b2/layout_w2_b2.yaml new file mode 100644 index 0000000..e25f3d0 --- /dev/null +++ b/examples/panel_assembly/w2_b2/layout_w2_b2.yaml @@ -0,0 +1,202 @@ +# Auto-generated from Excel sheet 'w2_b2' +# Re-generate: python examples/panel_assembly/w2_b2/generate_layout_from_excel.py + +panel: + xml: w2_b2_panel_base.xml + attach_to_body: panel_mount + +output_xml: generated/w2_b2_panel_assembly.xml + +layout: + coordinate_scale: 0.001 # mm -> m + face_axes: [x, z] + base_pos: [0.0, 30.0, 0.0] + default_quat: [0.7071068, -0.7071068, 0.0, 0.0] + remove_root_joints: true + +placements: + # seq 1 | Switch | wall (4,1) + - xml: objects/Switch_1.xml + pos: [350.0, 120.0] + row: 4 + col: 1 + # seq 2 | Knob | wall (4,2) + - xml: objects/Knob_2.xml + pos: [294.0, 120.0] + row: 4 + col: 2 + # seq 3 | Switch | wall (4,3) + - xml: objects/Switch_3.xml + pos: [238.0, 120.0] + row: 4 + col: 3 + # seq 4 | Switch | wall (4,4) | 2.4*1.9 + - xml: objects/Switch_4.xml + pos: [182.0, 120.0] + row: 4 + col: 4 + # seq 5 | Switch | wall (4,5) + - xml: objects/Switch_5.xml + pos: [126.0, 120.0] + row: 4 + col: 5 + # seq 6 | Switch | wall (4,6) + - xml: objects/Switch_6.xml + pos: [70.0, 120.0] + row: 4 + col: 6 + # seq 7 | Switch | wall (4,7) + - xml: objects/Switch_7.xml + pos: [10.0, 120.0] + row: 4 + col: 7 + # seq 8 | Switch | wall (4,8) + - xml: objects/Switch_8.xml + pos: [-50.0, 120.0] + row: 4 + col: 8 + # seq 9 | Switch | wall (4,9) + - xml: objects/Switch_9.xml + pos: [-110.0, 120.0] + row: 4 + col: 9 + # seq 10 | Switch | wall (4,10) + - xml: objects/Switch_10.xml + pos: [-170.0, 120.0] + row: 4 + col: 10 + # seq 11 | Knob | wall (4,11) | 厚30mm + - xml: objects/Knob_11.xml + pos: [-230.0, 120.0] + row: 4 + col: 11 + # seq 12 | Switch | wall (4,12) | 厚9mm + - xml: objects/Switch_12.xml + pos: [-290.0, 120.0] + row: 4 + col: 12 + # seq 13 | Switch | wall (4,13) | 厚15mm + - xml: objects/Switch_13.xml + pos: [-350.0, 120.0] + row: 4 + col: 13 + # seq 14 | Switch | wall (5,1) + - xml: objects/Switch_14.xml + pos: [350.0, 0.0] + row: 5 + col: 1 + # seq 15 | Switch | wall (5,2) + - xml: objects/Switch_15.xml + pos: [296.0, 0.0] + row: 5 + col: 2 + # seq 16 | Switch | wall (5,3) + - xml: objects/Switch_16.xml + pos: [242.0, 0.0] + row: 5 + col: 3 + # seq 17 | Switch | wall (5,4) + - xml: objects/Switch_17.xml + pos: [188.0, 0.0] + row: 5 + col: 4 + # seq 18 | Switch | wall (5,5) + - xml: objects/Switch_18.xml + pos: [134.0, 0.0] + row: 5 + col: 5 + # seq 19 | Switch | wall (5,6) + - xml: objects/Switch_19.xml + pos: [70.0, 0.0] + row: 5 + col: 6 + # seq 20 | Stop | wall (5,8) + - xml: objects/Stop_20.xml + pos: [-70.0, 0.0] + row: 5 + col: 8 + # seq 21 | Switch | wall (5,9) | 直径2.1 + - xml: objects/Switch_21.xml + pos: [-140.0, 0.0] + row: 5 + col: 9 + # seq 22 | Switch | wall (5,10) + - xml: objects/Switch_22.xml + pos: [-210.0, 0.0] + row: 5 + col: 10 + # seq 23 | Switch | wall (5,11) + - xml: objects/Switch_23.xml + pos: [-280.0, 0.0] + row: 5 + col: 11 + # seq 24 | Stop | wall (5,12) | 厚20mm + - xml: objects/Stop_24.xml + pos: [-350.0, 0.0] + row: 5 + col: 12 + # seq 25 | Switch | wall (6,1) | 3*2.5 + - xml: objects/Switch_25.xml + pos: [350.0, -120.0] + row: 6 + col: 1 + # seq 26 | Switch | wall (6,2) + - xml: objects/Switch_26.xml + pos: [285.0, -120.0] + row: 6 + col: 2 + # seq 27 | Switch | wall (6,3) + - xml: objects/Switch_27.xml + pos: [220.0, -120.0] + row: 6 + col: 3 + # seq 28 | Switch | wall (6,4) + - xml: objects/Switch_28.xml + pos: [155.0, -120.0] + row: 6 + col: 4 + # seq 29 | Switch | wall (6,5) + - xml: objects/Switch_29.xml + pos: [90.0, -120.0] + row: 6 + col: 5 + # seq 30 | Switch | wall (6,6) + - xml: objects/Switch_30.xml + pos: [25.0, -120.0] + row: 6 + col: 6 + # seq 31 | Switch | wall (6,7) | 2.2*1.7 + - xml: objects/Switch_31.xml + pos: [-43.2, -120.0] + row: 6 + col: 7 + # seq 32 | Switch | wall (6,8) + - xml: objects/Switch_32.xml + pos: [-96.2, -120.0] + row: 6 + col: 8 + # seq 33 | Switch | wall (6,9) | 2*1.5 + - xml: objects/Switch_33.xml + pos: [-149.2, -120.0] + row: 6 + col: 9 + # seq 34 | Switch | wall (6,10) | 厚6mm + - xml: objects/Switch_34.xml + pos: [-202.2, -120.0] + row: 6 + col: 10 + # seq 35 | Switch | wall (6,11) + - xml: objects/Switch_35.xml + pos: [-255.2, -120.0] + row: 6 + col: 11 + # seq 36 | Switch | wall (6,12) + - xml: objects/Switch_36.xml + pos: [-308.2, -120.0] + row: 6 + col: 12 + # seq 37 | Switch | wall (6,13) + - xml: objects/Switch_37.xml + pos: [-361.2, -120.0] + row: 6 + col: 13 diff --git a/examples/panel_assembly/w2_b2/objects/Knob_11.xml b/examples/panel_assembly/w2_b2/objects/Knob_11.xml new file mode 100644 index 0000000..c359312 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Knob_11.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Knob_2.xml b/examples/panel_assembly/w2_b2/objects/Knob_2.xml new file mode 100644 index 0000000..fb47d66 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Knob_2.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Stop_20.xml b/examples/panel_assembly/w2_b2/objects/Stop_20.xml new file mode 100644 index 0000000..bfbabff --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Stop_20.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Stop_24.xml b/examples/panel_assembly/w2_b2/objects/Stop_24.xml new file mode 100644 index 0000000..9bed257 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Stop_24.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_1.xml b/examples/panel_assembly/w2_b2/objects/Switch_1.xml new file mode 100644 index 0000000..e4bdf02 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_1.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_10.xml b/examples/panel_assembly/w2_b2/objects/Switch_10.xml new file mode 100644 index 0000000..d1dcf12 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_10.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_12.xml b/examples/panel_assembly/w2_b2/objects/Switch_12.xml new file mode 100644 index 0000000..4fc4aac --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_12.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_13.xml b/examples/panel_assembly/w2_b2/objects/Switch_13.xml new file mode 100644 index 0000000..e7e1fdc --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_13.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_14.xml b/examples/panel_assembly/w2_b2/objects/Switch_14.xml new file mode 100644 index 0000000..0b80a20 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_14.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_15.xml b/examples/panel_assembly/w2_b2/objects/Switch_15.xml new file mode 100644 index 0000000..373bcf0 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_15.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_16.xml b/examples/panel_assembly/w2_b2/objects/Switch_16.xml new file mode 100644 index 0000000..1ddda96 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_16.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_17.xml b/examples/panel_assembly/w2_b2/objects/Switch_17.xml new file mode 100644 index 0000000..958d92f --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_17.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_18.xml b/examples/panel_assembly/w2_b2/objects/Switch_18.xml new file mode 100644 index 0000000..3a61053 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_18.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_19.xml b/examples/panel_assembly/w2_b2/objects/Switch_19.xml new file mode 100644 index 0000000..d147034 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_19.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_2.xml b/examples/panel_assembly/w2_b2/objects/Switch_2.xml new file mode 100644 index 0000000..be1d79e --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_2.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_21.xml b/examples/panel_assembly/w2_b2/objects/Switch_21.xml new file mode 100644 index 0000000..a16340e --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_21.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_22.xml b/examples/panel_assembly/w2_b2/objects/Switch_22.xml new file mode 100644 index 0000000..26377df --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_22.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_23.xml b/examples/panel_assembly/w2_b2/objects/Switch_23.xml new file mode 100644 index 0000000..b437327 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_23.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_25.xml b/examples/panel_assembly/w2_b2/objects/Switch_25.xml new file mode 100644 index 0000000..ebb576c --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_25.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_26.xml b/examples/panel_assembly/w2_b2/objects/Switch_26.xml new file mode 100644 index 0000000..524c9f8 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_26.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_27.xml b/examples/panel_assembly/w2_b2/objects/Switch_27.xml new file mode 100644 index 0000000..c693bb8 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_27.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_28.xml b/examples/panel_assembly/w2_b2/objects/Switch_28.xml new file mode 100644 index 0000000..abddf25 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_28.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_29.xml b/examples/panel_assembly/w2_b2/objects/Switch_29.xml new file mode 100644 index 0000000..b151eb5 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_29.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_3.xml b/examples/panel_assembly/w2_b2/objects/Switch_3.xml new file mode 100644 index 0000000..e130304 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_3.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_30.xml b/examples/panel_assembly/w2_b2/objects/Switch_30.xml new file mode 100644 index 0000000..bdd0f12 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_30.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_31.xml b/examples/panel_assembly/w2_b2/objects/Switch_31.xml new file mode 100644 index 0000000..cda7ad9 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_31.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_32.xml b/examples/panel_assembly/w2_b2/objects/Switch_32.xml new file mode 100644 index 0000000..2ef0a63 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_32.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_33.xml b/examples/panel_assembly/w2_b2/objects/Switch_33.xml new file mode 100644 index 0000000..f7b9bdb --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_33.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_34.xml b/examples/panel_assembly/w2_b2/objects/Switch_34.xml new file mode 100644 index 0000000..d7cddf6 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_34.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_35.xml b/examples/panel_assembly/w2_b2/objects/Switch_35.xml new file mode 100644 index 0000000..b3fe314 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_35.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_36.xml b/examples/panel_assembly/w2_b2/objects/Switch_36.xml new file mode 100644 index 0000000..33fca5d --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_36.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_37.xml b/examples/panel_assembly/w2_b2/objects/Switch_37.xml new file mode 100644 index 0000000..25cb3cd --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_37.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_4.xml b/examples/panel_assembly/w2_b2/objects/Switch_4.xml new file mode 100644 index 0000000..7e0cfb5 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_4.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_5.xml b/examples/panel_assembly/w2_b2/objects/Switch_5.xml new file mode 100644 index 0000000..fed79be --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_5.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_6.xml b/examples/panel_assembly/w2_b2/objects/Switch_6.xml new file mode 100644 index 0000000..a9c1ed1 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_6.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_7.xml b/examples/panel_assembly/w2_b2/objects/Switch_7.xml new file mode 100644 index 0000000..c392964 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_7.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_8.xml b/examples/panel_assembly/w2_b2/objects/Switch_8.xml new file mode 100644 index 0000000..2adc27e --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_8.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/objects/Switch_9.xml b/examples/panel_assembly/w2_b2/objects/Switch_9.xml new file mode 100644 index 0000000..dfe1157 --- /dev/null +++ b/examples/panel_assembly/w2_b2/objects/Switch_9.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w2_b2/w2_b2_panel_base.xml b/examples/panel_assembly/w2_b2/w2_b2_panel_base.xml new file mode 100644 index 0000000..f8e45a7 --- /dev/null +++ b/examples/panel_assembly/w2_b2/w2_b2_panel_base.xml @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/create_initial_objects.py b/examples/panel_assembly/w3_b1/create_initial_objects.py new file mode 100644 index 0000000..057f84d --- /dev/null +++ b/examples/panel_assembly/w3_b1/create_initial_objects.py @@ -0,0 +1,88 @@ +"""One-time script: create the initial switch XMLs for w3_b1 in objects/. + +Each switch is 8.6cm x 8.6cm square, 7mm thick, default black metallic. +""" + +from __future__ import annotations + +from pathlib import Path + +OBJECTS_DIR = Path(__file__).parent / "objects" + +# Geometry (metres) +BTN_HALF = 0.043 +BTN_FACE_HALF = 0.040 +BEZEL_HALF_Z = 0.001 +BTN_HALF_Z = 0.0035 + +# Default black metallic +BEZEL_RGBA = "0.05 0.05 0.07 1" +BTN_RGBA = "0.10 0.10 0.13 1" +SPECULAR = "0.7" +SHININESS = "0.8" + +# 26 switches from Excel w3_b1 +# (class_name, x_mm, y_mm) +# Row 1 (y=120): 13 switches; positions 1-5,10-13 have no class_name in Excel +SWITCHES = [ + ("w3b1_Switch_01", 349.8, 120.0), # 1 (3,1,1) + ("w3b1_Switch_02", 293.8, 120.0), # 2 (3,1,2) + ("w3b1_Switch_03", 237.8, 120.0), # 3 (3,1,3) + ("w3b1_Switch_04", 181.8, 120.0), # 4 (3,1,4) + ("w3b1_Switch_05", 125.8, 120.0), # 5 (3,1,5) + ("Switch_Quantity1_36", 69.8, 120.0), # 6 (3,1,6) + ("Switch_Quantity1_37", 9.8, 120.0), # 7 (3,1,7) + ("Switch_Quantity1_38", -50.2, 120.0), # 8 (3,1,8) + ("Switch_Quantity1_39", -110.2, 120.0), # 9 (3,1,9) + ("w3b1_Switch_10", -170.2, 120.0), # 10 (3,1,10) + ("w3b1_Switch_11", -230.2, 120.0), # 11 (3,1,11) + ("w3b1_Switch_12", -290.2, 120.0), # 12 (3,1,12) + ("w3b1_Switch_13", -349.8, 120.0), # 13 (3,1,13) + # Row 2 (y=0): 6 switches (no position at col 4) + ("Switch_Quantity3_04", 349.8, 0.0), # 14 (3,2,1) + ("Switch_Quantity3_05", 233.2, 0.0), # 15 (3,2,2) + ("Switch_Quantity2_03", 116.6, 0.0), # 16 (3,2,3) + ("Switch_Quantity1_40", -116.6, 0.0), # 17 (3,2,5) + ("Switch_Quantity1_41", -233.2, 0.0), # 18 (3,2,6) + ("Switch_Quantity1_42", -349.8, 0.0), # 19 (3,2,7) + # Row 3 (y=-120): 7 switches + ("Switch_Quantity2_04", 349.8, -120.0), # 20 (3,3,1) + ("Switch_Quantity2_05", 233.2, -120.0), # 21 (3,3,2) + ("Toogle_Quantity4_01", 116.6, -120.0), # 22 (3,3,3) + ("Switch_Quantity2_06", 0.0, -120.0), # 23 (3,3,4) + ("Switch_Quantity1_43", -116.6, -120.0), # 24 (3,3,5) + ("Switch_Quantity1_44", -233.2, -120.0), # 25 (3,3,6) + ("Toogle_Quantity1_04", -349.8, -120.0), # 26 (3,3,7) +] + + +def generate_switch_xml(class_name: str) -> str: + return f""" + + + + + + + + + + +""" + + +def main() -> None: + OBJECTS_DIR.mkdir(exist_ok=True) + for class_name, x, y in SWITCHES: + path = OBJECTS_DIR / f"{class_name}.xml" + path.write_text(generate_switch_xml(class_name), encoding="utf-8") + print(f" {path.name}") + print(f"\nCreated {len(SWITCHES)} switch XMLs in {OBJECTS_DIR}") + + +if __name__ == "__main__": + main() diff --git a/examples/panel_assembly/w3_b1/generate_w3_b1.py b/examples/panel_assembly/w3_b1/generate_w3_b1.py new file mode 100644 index 0000000..54e4b5d --- /dev/null +++ b/examples/panel_assembly/w3_b1/generate_w3_b1.py @@ -0,0 +1,176 @@ +"""Generate w3_b1 panel assembly from objects/ XML files. + +Reads switch XMLs from objects/ and assembles them into the final panel. +Edit objects/*.xml to customise, then re-run this script. +""" + +from __future__ import annotations + +from pathlib import Path +from xml.etree import ElementTree as ET + +BASE_DIR = Path(__file__).parent + +# 17 switches from Excel w3_b1 (positions 1-5, 10-13 in row 1 have no switch yet) +# (class_name, x_mm, y_mm, wall_row, wall_col) +SWITCHES = [ + # Row 1 (y=120): 4 switches (cols 6-9 only) + ("Switch_Quantity1_36", 69.8, 120.0, 1, 6), + ("Switch_Quantity1_37", 9.8, 120.0, 1, 7), + ("Switch_Quantity1_38", -50.2, 120.0, 1, 8), + ("Switch_Quantity1_39", -110.2, 120.0, 1, 9), + # Row 2 (y=0): 6 switches (no col 4) + ("Switch_Quantity3_04", 349.8, 0.0, 2, 1), + ("Switch_Quantity3_05", 233.2, 0.0, 2, 2), + ("Switch_Quantity2_03", 116.6, 0.0, 2, 3), + ("Switch_Quantity1_40", -116.6, 0.0, 2, 5), + ("Switch_Quantity1_41", -233.2, 0.0, 2, 6), + ("Switch_Quantity1_42", -349.8, 0.0, 2, 7), + # Row 3 (y=-120): 7 switches + ("Switch_Quantity2_04", 349.8, -120.0, 3, 1), + ("Switch_Quantity2_05", 233.2, -120.0, 3, 2), + ("Toogle_Quantity4_01", 116.6, -120.0, 3, 3), + ("Switch_Quantity2_06", 0.0, -120.0, 3, 4), + ("Switch_Quantity1_43", -116.6, -120.0, 3, 5), + ("Switch_Quantity1_44", -233.2, -120.0, 3, 6), + ("Toogle_Quantity1_04", -349.8, -120.0, 3, 7), +] + +PANEL_HALF_X = 0.81 +PANEL_HALF_Y = 0.025 +PANEL_HALF_Z = 0.28 +BASE_POS_Y = 30.0 + + +def parse_switch_xml(xml_path: Path) -> tuple[list[ET.Element], list[ET.Element], str]: + tree = ET.parse(xml_path) + root = tree.getroot() + materials = list(root.iter("material")) + body = root.find(".//worldbody/body") + geoms = list(body.iter("geom")) if body is not None else [] + body_name = body.get("name", "") if body is not None else "" + return materials, geoms, body_name + + +def generate_layout_yaml() -> str: + lines = [ + "# w3_b1 switch wall layout", + f"# {len(SWITCHES)} switches (row 1 positions 1-5,10-13 reserved)", + "", + "panel:", + " xml: w3_b1_panel_base.xml", + " attach_to_body: panel_mount", + "", + "output_xml: generated/w3_b1_panel_assembly.xml", + "", + "layout:", + " coordinate_scale: 0.001", + " face_axes: [x, z]", + f" base_pos: [0.0, {BASE_POS_Y}, 0.0]", + " default_quat: [0.7071068, -0.7071068, 0.0, 0.0]", + " remove_root_joints: true", + "", + "placements:", + ] + for idx, (cname, x, y, r, c) in enumerate(SWITCHES, 1): + lines.append(f" # {idx}. {cname} | wall ({r},{c})") + lines.append(f" - xml: objects/{cname}.xml") + lines.append(f" pos: [{x}, {y}]") + lines.append(f" row: {r}") + lines.append(f" col: {c}") + return "\n".join(lines) + "\n" + + +def generate_panel_base_xml() -> str: + return f""" + + + + + + + +""" + + +def generate_assembly_xml() -> str: + coord_scale = 0.001 + base_y = BASE_POS_Y * coord_scale + quat = "0.7071068 -0.7071068 0 0" + objects_dir = BASE_DIR / "objects" + + asset_lines: list[str] = [] + slot_lines: list[str] = [] + + for cname, x_mm, y_mm, r, c in SWITCHES: + xml_path = objects_dir / f"{cname}.xml" + if not xml_path.exists(): + print(f" WARNING: {xml_path.name} not found, skipping") + continue + materials, geoms, body_name = parse_switch_xml(xml_path) + x_m = x_mm * coord_scale + z_m = y_mm * coord_scale + slot_name = f"panel_slot_r{r}_c{c}" + assembled_body = f"{body_name}_r{r}_c{c}" if body_name else f"{cname}_r{r}_c{c}" + + for mat in materials: + asset_lines.append(f" {ET.tostring(mat, encoding='unicode').strip()}") + + slot_lines.append( + f' ' + ) + slot_lines.append(f' ') + for geom in geoms: + orig = geom.get("name", "") + if orig: + geom.set("name", f"{orig}__{slot_name}") + slot_lines.append( + f" {ET.tostring(geom, encoding='unicode').strip()}" + ) + slot_lines.append(" ") + slot_lines.append(" ") + + return f""" + + +{chr(10).join(asset_lines)} + + + + + +{chr(10).join(slot_lines)} + + +""" + + +def main() -> None: + objects_dir = BASE_DIR / "objects" + if not objects_dir.exists(): + print(f"ERROR: {objects_dir} does not exist.") + return + (BASE_DIR / "generated").mkdir(exist_ok=True) + + (BASE_DIR / "layout_w3_b1.yaml").write_text( + generate_layout_yaml(), encoding="utf-8" + ) + print(" Created layout_w3_b1.yaml") + + (BASE_DIR / "w3_b1_panel_base.xml").write_text( + generate_panel_base_xml(), encoding="utf-8" + ) + print(" Created w3_b1_panel_base.xml") + + (BASE_DIR / "generated" / "w3_b1_panel_assembly.xml").write_text( + generate_assembly_xml(), encoding="utf-8" + ) + print(" Created generated/w3_b1_panel_assembly.xml") + + print(f"\nDone. Assembly built from {len(SWITCHES)} switches.") + + +if __name__ == "__main__": + main() diff --git a/examples/panel_assembly/w3_b1/generated/w3_b1_panel_assembly.xml b/examples/panel_assembly/w3_b1/generated/w3_b1_panel_assembly.xml new file mode 100644 index 0000000..77e7951 --- /dev/null +++ b/examples/panel_assembly/w3_b1/generated/w3_b1_panel_assembly.xml @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/layout_w3_b1.yaml b/examples/panel_assembly/w3_b1/layout_w3_b1.yaml new file mode 100644 index 0000000..a4f5053 --- /dev/null +++ b/examples/panel_assembly/w3_b1/layout_w3_b1.yaml @@ -0,0 +1,102 @@ +# w3_b1 switch wall layout +# 17 switches (row 1 positions 1-5,10-13 reserved) + +panel: + xml: w3_b1_panel_base.xml + attach_to_body: panel_mount + +output_xml: generated/w3_b1_panel_assembly.xml + +layout: + coordinate_scale: 0.001 + face_axes: [x, z] + base_pos: [0.0, 30.0, 0.0] + default_quat: [0.7071068, -0.7071068, 0.0, 0.0] + remove_root_joints: true + +placements: + # 1. Switch_Quantity1_36 | wall (1,6) + - xml: objects/Switch_Quantity1_36.xml + pos: [69.8, 120.0] + row: 1 + col: 6 + # 2. Switch_Quantity1_37 | wall (1,7) + - xml: objects/Switch_Quantity1_37.xml + pos: [9.8, 120.0] + row: 1 + col: 7 + # 3. Switch_Quantity1_38 | wall (1,8) + - xml: objects/Switch_Quantity1_38.xml + pos: [-50.2, 120.0] + row: 1 + col: 8 + # 4. Switch_Quantity1_39 | wall (1,9) + - xml: objects/Switch_Quantity1_39.xml + pos: [-110.2, 120.0] + row: 1 + col: 9 + # 5. Switch_Quantity3_04 | wall (2,1) + - xml: objects/Switch_Quantity3_04.xml + pos: [349.8, 0.0] + row: 2 + col: 1 + # 6. Switch_Quantity3_05 | wall (2,2) + - xml: objects/Switch_Quantity3_05.xml + pos: [233.2, 0.0] + row: 2 + col: 2 + # 7. Switch_Quantity2_03 | wall (2,3) + - xml: objects/Switch_Quantity2_03.xml + pos: [116.6, 0.0] + row: 2 + col: 3 + # 8. Switch_Quantity1_40 | wall (2,5) + - xml: objects/Switch_Quantity1_40.xml + pos: [-116.6, 0.0] + row: 2 + col: 5 + # 9. Switch_Quantity1_41 | wall (2,6) + - xml: objects/Switch_Quantity1_41.xml + pos: [-233.2, 0.0] + row: 2 + col: 6 + # 10. Switch_Quantity1_42 | wall (2,7) + - xml: objects/Switch_Quantity1_42.xml + pos: [-349.8, 0.0] + row: 2 + col: 7 + # 11. Switch_Quantity2_04 | wall (3,1) + - xml: objects/Switch_Quantity2_04.xml + pos: [349.8, -120.0] + row: 3 + col: 1 + # 12. Switch_Quantity2_05 | wall (3,2) + - xml: objects/Switch_Quantity2_05.xml + pos: [233.2, -120.0] + row: 3 + col: 2 + # 13. Toogle_Quantity4_01 | wall (3,3) + - xml: objects/Toogle_Quantity4_01.xml + pos: [116.6, -120.0] + row: 3 + col: 3 + # 14. Switch_Quantity2_06 | wall (3,4) + - xml: objects/Switch_Quantity2_06.xml + pos: [0.0, -120.0] + row: 3 + col: 4 + # 15. Switch_Quantity1_43 | wall (3,5) + - xml: objects/Switch_Quantity1_43.xml + pos: [-116.6, -120.0] + row: 3 + col: 5 + # 16. Switch_Quantity1_44 | wall (3,6) + - xml: objects/Switch_Quantity1_44.xml + pos: [-233.2, -120.0] + row: 3 + col: 6 + # 17. Toogle_Quantity1_04 | wall (3,7) + - xml: objects/Toogle_Quantity1_04.xml + pos: [-349.8, -120.0] + row: 3 + col: 7 diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_36.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_36.xml new file mode 100644 index 0000000..406a3a1 --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_36.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_37.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_37.xml new file mode 100644 index 0000000..19e2320 --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_37.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_38.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_38.xml new file mode 100644 index 0000000..a9be5c0 --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_38.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_39.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_39.xml new file mode 100644 index 0000000..c938366 --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_39.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_40.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_40.xml new file mode 100644 index 0000000..e6ec776 --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_40.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_41.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_41.xml new file mode 100644 index 0000000..abaac5f --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_41.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_42.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_42.xml new file mode 100644 index 0000000..a0321dc --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_42.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_43.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_43.xml new file mode 100644 index 0000000..67208ae --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_43.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_44.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_44.xml new file mode 100644 index 0000000..f2ce7ec --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity1_44.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity2_03.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity2_03.xml new file mode 100644 index 0000000..9df7890 --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity2_03.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity2_04.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity2_04.xml new file mode 100644 index 0000000..572e38f --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity2_04.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity2_05.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity2_05.xml new file mode 100644 index 0000000..50abbd2 --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity2_05.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity2_06.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity2_06.xml new file mode 100644 index 0000000..95b319f --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity2_06.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity3_04.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity3_04.xml new file mode 100644 index 0000000..4160b29 --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity3_04.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Switch_Quantity3_05.xml b/examples/panel_assembly/w3_b1/objects/Switch_Quantity3_05.xml new file mode 100644 index 0000000..522805b --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Switch_Quantity3_05.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Toogle_Quantity1_04.xml b/examples/panel_assembly/w3_b1/objects/Toogle_Quantity1_04.xml new file mode 100644 index 0000000..380184c --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Toogle_Quantity1_04.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/Toogle_Quantity4_01.xml b/examples/panel_assembly/w3_b1/objects/Toogle_Quantity4_01.xml new file mode 100644 index 0000000..901b938 --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/Toogle_Quantity4_01.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/w3b1_Switch_01.xml b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_01.xml new file mode 100644 index 0000000..ebecec1 --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_01.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/w3b1_Switch_02.xml b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_02.xml new file mode 100644 index 0000000..440bc7a --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_02.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/w3b1_Switch_03.xml b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_03.xml new file mode 100644 index 0000000..cfbf32e --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_03.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/w3b1_Switch_04.xml b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_04.xml new file mode 100644 index 0000000..10b60e8 --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_04.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/w3b1_Switch_05.xml b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_05.xml new file mode 100644 index 0000000..54537aa --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_05.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/w3b1_Switch_10.xml b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_10.xml new file mode 100644 index 0000000..0aab535 --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_10.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/w3b1_Switch_11.xml b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_11.xml new file mode 100644 index 0000000..67bfa22 --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_11.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/w3b1_Switch_12.xml b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_12.xml new file mode 100644 index 0000000..1bd6ea9 --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_12.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/objects/w3b1_Switch_13.xml b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_13.xml new file mode 100644 index 0000000..624656d --- /dev/null +++ b/examples/panel_assembly/w3_b1/objects/w3b1_Switch_13.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/examples/panel_assembly/w3_b1/view_panel.py b/examples/panel_assembly/w3_b1/view_panel.py new file mode 100644 index 0000000..b29e1f7 --- /dev/null +++ b/examples/panel_assembly/w3_b1/view_panel.py @@ -0,0 +1,11 @@ +"""View the w3_b1 panel assembly in MuJoCo interactive viewer.""" + +from pathlib import Path + +import mujoco +import mujoco.viewer + +XML_PATH = Path(__file__).parent / "generated" / "w3_b1_panel_assembly.xml" +model = mujoco.MjModel.from_xml_path(str(XML_PATH)) +data = mujoco.MjData(model) +mujoco.viewer.launch(model, data) diff --git a/examples/panel_assembly/w3_b1/w3_b1_panel_base.xml b/examples/panel_assembly/w3_b1/w3_b1_panel_base.xml new file mode 100644 index 0000000..e3b96dc --- /dev/null +++ b/examples/panel_assembly/w3_b1/w3_b1_panel_base.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/generated/w2_b2_with_objects.xml b/examples/panel_assembly_excel/w2_b2/generated/w2_b2_with_objects.xml new file mode 100644 index 0000000..a1f8d4c --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/generated/w2_b2_with_objects.xml @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/layout.yaml b/examples/panel_assembly_excel/w2_b2/layout.yaml new file mode 100644 index 0000000..3d81883 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/layout.yaml @@ -0,0 +1,712 @@ +panel: + xml: panel_base.xml + attach_to_body: panel_mount +output_xml: generated/w2_b2_with_objects.xml +layout: + coordinate_scale: 0.001 + face_axes: + - x + - z + x_coords: + - -361.2 + - -350.0 + - -308.2 + - -290.0 + - -280.0 + - -255.2 + - -230.0 + - -210.0 + - -202.2 + - -170.0 + - -149.2 + - -140.0 + - -110.0 + - -96.2 + - -70.0 + - -50.0 + - -43.2 + - 10.0 + - 25.0 + - 70.0 + - 90.0 + - 126.0 + - 134.0 + - 155.0 + - 182.0 + - 188.0 + - 220.0 + - 238.0 + - 242.0 + - 285.0 + - 294.0 + - 296.0 + - 350.0 + y_coords: + - 120.0 + - 0.0 + - -120.0 + base_pos: + - 0.0 + - 15.0 + - 0.0 + default_quat: + - 0.7071068 + - -0.7071068 + - 0.0 + - 0.0 + remove_root_joints: true +placements: +- - null + - xml: objects/seq_13_switch_quantity1_16.xml + slot_name: w2_b2_slot_seq_13 + mounted_body_name: w2_b2_seq_13 + sequence: 13 + category: Switch + class_name: Switch_Quantity1_16 + button_class: '1_1' + wire_number: '47' + center_xy_mm: + - -350.0 + - 120.0 + source_location: + - 2 + - 4 + - 12 + note: 厚15mm + - null + - xml: objects/seq_12_switch_quantity1_15.xml + slot_name: w2_b2_slot_seq_12 + mounted_body_name: w2_b2_seq_12 + sequence: 12 + category: Switch + class_name: Switch_Quantity1_15 + button_class: '1_1' + wire_number: '46' + center_xy_mm: + - -290.0 + - 120.0 + source_location: + - 2 + - 4 + - 11 + note: 厚9mm + - null + - null + - xml: objects/seq_11_knob_quantity1_04.xml + slot_name: w2_b2_slot_seq_11 + mounted_body_name: w2_b2_seq_11 + sequence: 11 + category: Knob + class_name: Knob_Quantity1_04 + button_class: '1_1' + wire_number: '45' + center_xy_mm: + - -230.0 + - 120.0 + source_location: + - 2 + - 4 + - 10 + note: 厚30mm + - null + - null + - xml: objects/seq_10_switch_quantity1_14.xml + slot_name: w2_b2_slot_seq_10 + mounted_body_name: w2_b2_seq_10 + sequence: 10 + category: Switch + class_name: Switch_Quantity1_14 + button_class: '1_1' + wire_number: '44' + center_xy_mm: + - -170.0 + - 120.0 + source_location: + - 2 + - 4 + - 9 + note: null + - null + - null + - xml: objects/seq_09_switch_quantity1_13.xml + slot_name: w2_b2_slot_seq_09 + mounted_body_name: w2_b2_seq_09 + sequence: 9 + category: Switch + class_name: Switch_Quantity1_13 + button_class: '1_1' + wire_number: '43' + center_xy_mm: + - -110.0 + - 120.0 + source_location: + - 2 + - 4 + - 9 + note: null + - null + - null + - xml: objects/seq_08_switch_quantity1_12.xml + slot_name: w2_b2_slot_seq_08 + mounted_body_name: w2_b2_seq_08 + sequence: 8 + category: Switch + class_name: Switch_Quantity1_12 + button_class: '1_1' + wire_number: '42' + center_xy_mm: + - -50.0 + - 120.0 + source_location: + - 2 + - 4 + - 8 + note: null + - null + - xml: objects/seq_07_switch_quantity1_11.xml + slot_name: w2_b2_slot_seq_07 + mounted_body_name: w2_b2_seq_07 + sequence: 7 + category: Switch + class_name: Switch_Quantity1_11 + button_class: '1_1' + wire_number: '41' + center_xy_mm: + - 10.0 + - 120.0 + source_location: + - 2 + - 4 + - 7 + note: null + - null + - xml: objects/seq_06_switch_quantity1_10.xml + slot_name: w2_b2_slot_seq_06 + mounted_body_name: w2_b2_seq_06 + sequence: 6 + category: Switch + class_name: Switch_Quantity1_10 + button_class: '1_1' + wire_number: '40' + center_xy_mm: + - 70.0 + - 120.0 + source_location: + - 2 + - 4 + - 6 + note: null + - null + - xml: objects/seq_05_switch_quantity1_09.xml + slot_name: w2_b2_slot_seq_05 + mounted_body_name: w2_b2_seq_05 + sequence: 5 + category: Switch + class_name: Switch_Quantity1_09 + button_class: '1_1' + wire_number: '39' + center_xy_mm: + - 126.0 + - 120.0 + source_location: + - 2 + - 4 + - 5 + note: null + - null + - null + - xml: objects/seq_04_switch_quantity1_08.xml + slot_name: w2_b2_slot_seq_04 + mounted_body_name: w2_b2_seq_04 + sequence: 4 + category: Switch + class_name: Switch_Quantity1_08 + button_class: '1_1' + wire_number: '38' + center_xy_mm: + - 182.0 + - 120.0 + source_location: + - 2 + - 4 + - 4 + note: 2.4*1.9 + - null + - null + - xml: objects/seq_03_switch_quantity1_07.xml + slot_name: w2_b2_slot_seq_03 + mounted_body_name: w2_b2_seq_03 + sequence: 3 + category: Switch + class_name: Switch_Quantity1_07 + button_class: '1_1' + wire_number: '37' + center_xy_mm: + - 238.0 + - 120.0 + source_location: + - 2 + - 4 + - 3 + note: null + - null + - null + - xml: objects/seq_02_knob_quantity1_03.xml + slot_name: w2_b2_slot_seq_02 + mounted_body_name: w2_b2_seq_02 + sequence: 2 + category: Knob + class_name: Knob_Quantity1_03 + button_class: '1_1' + wire_number: '36' + center_xy_mm: + - 294.0 + - 120.0 + source_location: + - 2 + - 4 + - 2 + note: null + - null + - xml: objects/seq_01_switch_quantity1_06.xml + slot_name: w2_b2_slot_seq_01 + mounted_body_name: w2_b2_seq_01 + sequence: 1 + category: Switch + class_name: Switch_Quantity1_06 + button_class: '1_1' + wire_number: '35' + center_xy_mm: + - 350.0 + - 120.0 + source_location: + - 2 + - 4 + - 1 + note: null +- - null + - xml: objects/seq_24_stop_quantity1_2.xml + slot_name: w2_b2_slot_seq_24 + mounted_body_name: w2_b2_seq_24 + sequence: 24 + category: Stop + class_name: Stop_Quantity1_2 + button_class: '1_1' + wire_number: '58' + center_xy_mm: + - -350.0 + - 0.0 + source_location: + - 2 + - 5 + - 12 + note: 厚20mm + - null + - null + - xml: objects/seq_23_switch_quantity1_25.xml + slot_name: w2_b2_slot_seq_23 + mounted_body_name: w2_b2_seq_23 + sequence: 23 + category: Switch + class_name: Switch_Quantity1_25 + button_class: '1_1' + wire_number: '57' + center_xy_mm: + - -280.0 + - 0.0 + source_location: + - 2 + - 5 + - 11 + note: null + - null + - null + - xml: objects/seq_22_switch_quantity1_24.xml + slot_name: w2_b2_slot_seq_22 + mounted_body_name: w2_b2_seq_22 + sequence: 22 + category: Switch + class_name: Switch_Quantity1_24 + button_class: '1_1' + wire_number: '56' + center_xy_mm: + - -210.0 + - 0.0 + source_location: + - 2 + - 5 + - 10 + note: null + - null + - null + - null + - xml: objects/seq_21_switch_quantity1_23.xml + slot_name: w2_b2_slot_seq_21 + mounted_body_name: w2_b2_seq_21 + sequence: 21 + category: Switch + class_name: Switch_Quantity1_23 + button_class: '1_1' + wire_number: '55' + center_xy_mm: + - -140.0 + - 0.0 + source_location: + - 2 + - 5 + - 9 + note: 直径2.1 + - null + - null + - xml: objects/seq_20_stop_quantity1_1.xml + slot_name: w2_b2_slot_seq_20 + mounted_body_name: w2_b2_seq_20 + sequence: 20 + category: Stop + class_name: Stop_Quantity1_1 + button_class: '1_1' + wire_number: '54' + center_xy_mm: + - -70.0 + - 0.0 + source_location: + - 2 + - 5 + - 8 + note: null + - null + - null + - null + - null + - xml: objects/seq_19_switch_quantity1_22.xml + slot_name: w2_b2_slot_seq_19 + mounted_body_name: w2_b2_seq_19 + sequence: 19 + category: Switch + class_name: Switch_Quantity1_22 + button_class: '1_1' + wire_number: '53' + center_xy_mm: + - 70.0 + - 0.0 + source_location: + - 2 + - 5 + - 6 + note: null + - null + - null + - xml: objects/seq_18_switch_quantity1_21.xml + slot_name: w2_b2_slot_seq_18 + mounted_body_name: w2_b2_seq_18 + sequence: 18 + category: Switch + class_name: Switch_Quantity1_21 + button_class: '1_1' + wire_number: '52' + center_xy_mm: + - 134.0 + - 0.0 + source_location: + - 2 + - 5 + - 5 + note: null + - null + - null + - xml: objects/seq_17_switch_quantity1_20.xml + slot_name: w2_b2_slot_seq_17 + mounted_body_name: w2_b2_seq_17 + sequence: 17 + category: Switch + class_name: Switch_Quantity1_20 + button_class: '1_1' + wire_number: '51' + center_xy_mm: + - 188.0 + - 0.0 + source_location: + - 2 + - 5 + - 4 + note: null + - null + - null + - xml: objects/seq_16_switch_quantity1_19.xml + slot_name: w2_b2_slot_seq_16 + mounted_body_name: w2_b2_seq_16 + sequence: 16 + category: Switch + class_name: Switch_Quantity1_19 + button_class: '1_1' + wire_number: '50' + center_xy_mm: + - 242.0 + - 0.0 + source_location: + - 2 + - 5 + - 3 + note: null + - null + - null + - xml: objects/seq_15_switch_quantity1_18.xml + slot_name: w2_b2_slot_seq_15 + mounted_body_name: w2_b2_seq_15 + sequence: 15 + category: Switch + class_name: Switch_Quantity1_18 + button_class: '1_1' + wire_number: '49' + center_xy_mm: + - 296.0 + - 0.0 + source_location: + - 2 + - 5 + - 2 + note: null + - xml: objects/seq_14_switch_quantity1_17.xml + slot_name: w2_b2_slot_seq_14 + mounted_body_name: w2_b2_seq_14 + sequence: 14 + category: Switch + class_name: Switch_Quantity1_17 + button_class: '1_1' + wire_number: '48' + center_xy_mm: + - 350.0 + - 0.0 + source_location: + - 2 + - 5 + - 1 + note: null +- - xml: objects/seq_37_unknown.xml + slot_name: w2_b2_slot_seq_37 + mounted_body_name: w2_b2_seq_37 + sequence: 37 + category: null + class_name: null + button_class: null + wire_number: null + center_xy_mm: + - -361.2 + - -120.0 + source_location: + - 2 + - 6 + - 13 + note: null + - null + - xml: objects/seq_36_unknown.xml + slot_name: w2_b2_slot_seq_36 + mounted_body_name: w2_b2_seq_36 + sequence: 36 + category: null + class_name: null + button_class: null + wire_number: null + center_xy_mm: + - -308.2 + - -120.0 + source_location: + - 2 + - 6 + - 12 + note: null + - null + - null + - xml: objects/seq_35_unknown.xml + slot_name: w2_b2_slot_seq_35 + mounted_body_name: w2_b2_seq_35 + sequence: 35 + category: null + class_name: null + button_class: null + wire_number: null + center_xy_mm: + - -255.2 + - -120.0 + source_location: + - 2 + - 6 + - 11 + note: null + - null + - null + - xml: objects/seq_34_switch_quantity1_35.xml + slot_name: w2_b2_slot_seq_34 + mounted_body_name: w2_b2_seq_34 + sequence: 34 + category: Switch + class_name: Switch_Quantity1_35 + button_class: '1_1' + wire_number: '68' + center_xy_mm: + - -202.2 + - -120.0 + source_location: + - 2 + - 6 + - 10 + note: 厚6mm + - null + - xml: objects/seq_33_switch_quantity1_34.xml + slot_name: w2_b2_slot_seq_33 + mounted_body_name: w2_b2_seq_33 + sequence: 33 + category: Switch + class_name: Switch_Quantity1_34 + button_class: '1_1' + wire_number: '67' + center_xy_mm: + - -149.2 + - -120.0 + source_location: + - 2 + - 6 + - 9 + note: 2*1.5 + - null + - null + - xml: objects/seq_32_switch_quantity1_33.xml + slot_name: w2_b2_slot_seq_32 + mounted_body_name: w2_b2_seq_32 + sequence: 32 + category: Switch + class_name: Switch_Quantity1_33 + button_class: '1_1' + wire_number: '66' + center_xy_mm: + - -96.2 + - -120.0 + source_location: + - 2 + - 6 + - 8 + note: null + - null + - null + - xml: objects/seq_31_switch_quantity1_32.xml + slot_name: w2_b2_slot_seq_31 + mounted_body_name: w2_b2_seq_31 + sequence: 31 + category: Switch + class_name: Switch_Quantity1_32 + button_class: '1_1' + wire_number: '65' + center_xy_mm: + - -43.2 + - -120.0 + source_location: + - 2 + - 6 + - 7 + note: 2.2*1.7 + - null + - xml: objects/seq_30_switch_quantity1_31.xml + slot_name: w2_b2_slot_seq_30 + mounted_body_name: w2_b2_seq_30 + sequence: 30 + category: Switch + class_name: Switch_Quantity1_31 + button_class: '1_1' + wire_number: '64' + center_xy_mm: + - 25.0 + - -120.0 + source_location: + - 2 + - 6 + - 6 + note: null + - null + - xml: objects/seq_29_switch_quantity1_30.xml + slot_name: w2_b2_slot_seq_29 + mounted_body_name: w2_b2_seq_29 + sequence: 29 + category: Switch + class_name: Switch_Quantity1_30 + button_class: '1_1' + wire_number: '63' + center_xy_mm: + - 90.0 + - -120.0 + source_location: + - 2 + - 6 + - 5 + note: null + - null + - null + - xml: objects/seq_28_switch_quantity1_29.xml + slot_name: w2_b2_slot_seq_28 + mounted_body_name: w2_b2_seq_28 + sequence: 28 + category: Switch + class_name: Switch_Quantity1_29 + button_class: '1_1' + wire_number: '62' + center_xy_mm: + - 155.0 + - -120.0 + source_location: + - 2 + - 6 + - 4 + note: null + - null + - null + - xml: objects/seq_27_switch_quantity1_28.xml + slot_name: w2_b2_slot_seq_27 + mounted_body_name: w2_b2_seq_27 + sequence: 27 + category: Switch + class_name: Switch_Quantity1_28 + button_class: '1_1' + wire_number: '61' + center_xy_mm: + - 220.0 + - -120.0 + source_location: + - 2 + - 6 + - 3 + note: null + - null + - null + - xml: objects/seq_26_switch_quantity1_27.xml + slot_name: w2_b2_slot_seq_26 + mounted_body_name: w2_b2_seq_26 + sequence: 26 + category: Switch + class_name: Switch_Quantity1_27 + button_class: '1_1' + wire_number: '60' + center_xy_mm: + - 285.0 + - -120.0 + source_location: + - 2 + - 6 + - 2 + note: null + - null + - null + - xml: objects/seq_25_switch_quantity1_26.xml + slot_name: w2_b2_slot_seq_25 + mounted_body_name: w2_b2_seq_25 + sequence: 25 + category: Switch + class_name: Switch_Quantity1_26 + button_class: '1_1' + wire_number: '59' + center_xy_mm: + - 350.0 + - -120.0 + source_location: + - 2 + - 6 + - 1 + note: 3*2.5 diff --git a/examples/panel_assembly_excel/w2_b2/objects/README.md b/examples/panel_assembly_excel/w2_b2/objects/README.md new file mode 100644 index 0000000..6043a0f --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/README.md @@ -0,0 +1,44 @@ +# w2_b2 Objects + +这些 XML 文件还没有创建好。后续你可以按下面的文件名把每个序号对应的按钮资产补进来, +然后直接运行面板装配脚本生成最终 XML。 + +## 预期文件 + +- `seq_01_switch_quantity1_06.xml` 序号 1 | Switch | Switch_Quantity1_06 | center=(350, 120) mm +- `seq_02_knob_quantity1_03.xml` 序号 2 | Knob | Knob_Quantity1_03 | center=(294, 120) mm +- `seq_03_switch_quantity1_07.xml` 序号 3 | Switch | Switch_Quantity1_07 | center=(238, 120) mm +- `seq_04_switch_quantity1_08.xml` 序号 4 | Switch | Switch_Quantity1_08 | center=(182, 120) mm +- `seq_05_switch_quantity1_09.xml` 序号 5 | Switch | Switch_Quantity1_09 | center=(126, 120) mm +- `seq_06_switch_quantity1_10.xml` 序号 6 | Switch | Switch_Quantity1_10 | center=(70, 120) mm +- `seq_07_switch_quantity1_11.xml` 序号 7 | Switch | Switch_Quantity1_11 | center=(10, 120) mm +- `seq_08_switch_quantity1_12.xml` 序号 8 | Switch | Switch_Quantity1_12 | center=(-50, 120) mm +- `seq_09_switch_quantity1_13.xml` 序号 9 | Switch | Switch_Quantity1_13 | center=(-110, 120) mm +- `seq_10_switch_quantity1_14.xml` 序号 10 | Switch | Switch_Quantity1_14 | center=(-170, 120) mm +- `seq_11_knob_quantity1_04.xml` 序号 11 | Knob | Knob_Quantity1_04 | center=(-230, 120) mm +- `seq_12_switch_quantity1_15.xml` 序号 12 | Switch | Switch_Quantity1_15 | center=(-290, 120) mm +- `seq_13_switch_quantity1_16.xml` 序号 13 | Switch | Switch_Quantity1_16 | center=(-350, 120) mm +- `seq_14_switch_quantity1_17.xml` 序号 14 | Switch | Switch_Quantity1_17 | center=(350, 0) mm +- `seq_15_switch_quantity1_18.xml` 序号 15 | Switch | Switch_Quantity1_18 | center=(296, 0) mm +- `seq_16_switch_quantity1_19.xml` 序号 16 | Switch | Switch_Quantity1_19 | center=(242, 0) mm +- `seq_17_switch_quantity1_20.xml` 序号 17 | Switch | Switch_Quantity1_20 | center=(188, 0) mm +- `seq_18_switch_quantity1_21.xml` 序号 18 | Switch | Switch_Quantity1_21 | center=(134, 0) mm +- `seq_19_switch_quantity1_22.xml` 序号 19 | Switch | Switch_Quantity1_22 | center=(70, 0) mm +- `seq_20_stop_quantity1_1.xml` 序号 20 | Stop | Stop_Quantity1_1 | center=(-70, 0) mm +- `seq_21_switch_quantity1_23.xml` 序号 21 | Switch | Switch_Quantity1_23 | center=(-140, 0) mm +- `seq_22_switch_quantity1_24.xml` 序号 22 | Switch | Switch_Quantity1_24 | center=(-210, 0) mm +- `seq_23_switch_quantity1_25.xml` 序号 23 | Switch | Switch_Quantity1_25 | center=(-280, 0) mm +- `seq_24_stop_quantity1_2.xml` 序号 24 | Stop | Stop_Quantity1_2 | center=(-350, 0) mm +- `seq_25_switch_quantity1_26.xml` 序号 25 | Switch | Switch_Quantity1_26 | center=(350, -120) mm +- `seq_26_switch_quantity1_27.xml` 序号 26 | Switch | Switch_Quantity1_27 | center=(285, -120) mm +- `seq_27_switch_quantity1_28.xml` 序号 27 | Switch | Switch_Quantity1_28 | center=(220, -120) mm +- `seq_28_switch_quantity1_29.xml` 序号 28 | Switch | Switch_Quantity1_29 | center=(155, -120) mm +- `seq_29_switch_quantity1_30.xml` 序号 29 | Switch | Switch_Quantity1_30 | center=(90, -120) mm +- `seq_30_switch_quantity1_31.xml` 序号 30 | Switch | Switch_Quantity1_31 | center=(25, -120) mm +- `seq_31_switch_quantity1_32.xml` 序号 31 | Switch | Switch_Quantity1_32 | center=(-43.2, -120) mm +- `seq_32_switch_quantity1_33.xml` 序号 32 | Switch | Switch_Quantity1_33 | center=(-96.2, -120) mm +- `seq_33_switch_quantity1_34.xml` 序号 33 | Switch | Switch_Quantity1_34 | center=(-149.2, -120) mm +- `seq_34_switch_quantity1_35.xml` 序号 34 | Switch | Switch_Quantity1_35 | center=(-202.2, -120) mm +- `seq_35_unknown.xml` 序号 35 | center=(-255.2, -120) mm +- `seq_36_unknown.xml` 序号 36 | center=(-308.2, -120) mm +- `seq_37_unknown.xml` 序号 37 | center=(-361.2, -120) mm diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_01_switch_quantity1_06.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_01_switch_quantity1_06.xml new file mode 100644 index 0000000..98c9b8f --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_01_switch_quantity1_06.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_02_knob_quantity1_03.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_02_knob_quantity1_03.xml new file mode 100644 index 0000000..13d0b86 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_02_knob_quantity1_03.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_03_switch_quantity1_07.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_03_switch_quantity1_07.xml new file mode 100644 index 0000000..673d679 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_03_switch_quantity1_07.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_04_switch_quantity1_08.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_04_switch_quantity1_08.xml new file mode 100644 index 0000000..7805c5a --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_04_switch_quantity1_08.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_05_switch_quantity1_09.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_05_switch_quantity1_09.xml new file mode 100644 index 0000000..7a54c4d --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_05_switch_quantity1_09.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_06_switch_quantity1_10.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_06_switch_quantity1_10.xml new file mode 100644 index 0000000..cafae46 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_06_switch_quantity1_10.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_07_switch_quantity1_11.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_07_switch_quantity1_11.xml new file mode 100644 index 0000000..0e5855a --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_07_switch_quantity1_11.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_08_switch_quantity1_12.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_08_switch_quantity1_12.xml new file mode 100644 index 0000000..029f2ec --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_08_switch_quantity1_12.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_09_switch_quantity1_13.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_09_switch_quantity1_13.xml new file mode 100644 index 0000000..6ac9d5a --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_09_switch_quantity1_13.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_10_switch_quantity1_14.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_10_switch_quantity1_14.xml new file mode 100644 index 0000000..7733fdc --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_10_switch_quantity1_14.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_11_knob_quantity1_04.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_11_knob_quantity1_04.xml new file mode 100644 index 0000000..49870a4 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_11_knob_quantity1_04.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_12_switch_quantity1_15.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_12_switch_quantity1_15.xml new file mode 100644 index 0000000..252ce39 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_12_switch_quantity1_15.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_13_switch_quantity1_16.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_13_switch_quantity1_16.xml new file mode 100644 index 0000000..c84a329 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_13_switch_quantity1_16.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_14_switch_quantity1_17.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_14_switch_quantity1_17.xml new file mode 100644 index 0000000..1535139 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_14_switch_quantity1_17.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_15_switch_quantity1_18.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_15_switch_quantity1_18.xml new file mode 100644 index 0000000..cbf11d8 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_15_switch_quantity1_18.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_16_switch_quantity1_19.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_16_switch_quantity1_19.xml new file mode 100644 index 0000000..97d2867 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_16_switch_quantity1_19.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_17_switch_quantity1_20.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_17_switch_quantity1_20.xml new file mode 100644 index 0000000..feedf9c --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_17_switch_quantity1_20.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_18_switch_quantity1_21.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_18_switch_quantity1_21.xml new file mode 100644 index 0000000..6540966 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_18_switch_quantity1_21.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_19_switch_quantity1_22.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_19_switch_quantity1_22.xml new file mode 100644 index 0000000..80cb064 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_19_switch_quantity1_22.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_20_stop_quantity1_1.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_20_stop_quantity1_1.xml new file mode 100644 index 0000000..b038b47 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_20_stop_quantity1_1.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_21_switch_quantity1_23.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_21_switch_quantity1_23.xml new file mode 100644 index 0000000..36b3e6e --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_21_switch_quantity1_23.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_22_switch_quantity1_24.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_22_switch_quantity1_24.xml new file mode 100644 index 0000000..ddb2602 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_22_switch_quantity1_24.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_23_switch_quantity1_25.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_23_switch_quantity1_25.xml new file mode 100644 index 0000000..87b2ad6 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_23_switch_quantity1_25.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_24_stop_quantity1_2.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_24_stop_quantity1_2.xml new file mode 100644 index 0000000..8387ab9 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_24_stop_quantity1_2.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_25_switch_quantity1_26.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_25_switch_quantity1_26.xml new file mode 100644 index 0000000..d4fbb43 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_25_switch_quantity1_26.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_26_switch_quantity1_27.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_26_switch_quantity1_27.xml new file mode 100644 index 0000000..6ccbf69 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_26_switch_quantity1_27.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_27_switch_quantity1_28.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_27_switch_quantity1_28.xml new file mode 100644 index 0000000..618d0e1 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_27_switch_quantity1_28.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_28_switch_quantity1_29.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_28_switch_quantity1_29.xml new file mode 100644 index 0000000..d4a0c1b --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_28_switch_quantity1_29.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_29_switch_quantity1_30.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_29_switch_quantity1_30.xml new file mode 100644 index 0000000..cb58822 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_29_switch_quantity1_30.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_30_switch_quantity1_31.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_30_switch_quantity1_31.xml new file mode 100644 index 0000000..1bfd353 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_30_switch_quantity1_31.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_31_switch_quantity1_32.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_31_switch_quantity1_32.xml new file mode 100644 index 0000000..026777a --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_31_switch_quantity1_32.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_32_switch_quantity1_33.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_32_switch_quantity1_33.xml new file mode 100644 index 0000000..9f209b5 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_32_switch_quantity1_33.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_33_switch_quantity1_34.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_33_switch_quantity1_34.xml new file mode 100644 index 0000000..848eb4a --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_33_switch_quantity1_34.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_34_switch_quantity1_35.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_34_switch_quantity1_35.xml new file mode 100644 index 0000000..ac6b135 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_34_switch_quantity1_35.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_35_unknown.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_35_unknown.xml new file mode 100644 index 0000000..9f2e307 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_35_unknown.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_36_unknown.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_36_unknown.xml new file mode 100644 index 0000000..1672a40 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_36_unknown.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/objects/seq_37_unknown.xml b/examples/panel_assembly_excel/w2_b2/objects/seq_37_unknown.xml new file mode 100644 index 0000000..6e93708 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/objects/seq_37_unknown.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/panel_base.xml b/examples/panel_assembly_excel/w2_b2/panel_base.xml new file mode 100644 index 0000000..a2b691f --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/panel_base.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/panel_assembly_excel/w2_b2/switch_inventory.csv b/examples/panel_assembly_excel/w2_b2/switch_inventory.csv new file mode 100644 index 0000000..9b38492 --- /dev/null +++ b/examples/panel_assembly_excel/w2_b2/switch_inventory.csv @@ -0,0 +1,38 @@ +wall_board_name,sequence,category,button_count,class_name,button_class,center_x_mm,center_y_mm,location,wire_number,note,expected_xml +w2_b2,1,Switch,1,Switch_Quantity1_06,1_1,350,120,"(2, 4, 1)",35,,objects/seq_01_switch_quantity1_06.xml +w2_b2,2,Knob,1,Knob_Quantity1_03,1_1,294,120,"(2, 4, 2)",36,,objects/seq_02_knob_quantity1_03.xml +w2_b2,3,Switch,1,Switch_Quantity1_07,1_1,238,120,"(2, 4, 3)",37,,objects/seq_03_switch_quantity1_07.xml +w2_b2,4,Switch,1,Switch_Quantity1_08,1_1,182,120,"(2, 4, 4)",38,2.4*1.9,objects/seq_04_switch_quantity1_08.xml +w2_b2,5,Switch,1,Switch_Quantity1_09,1_1,126,120,"(2, 4, 5)",39,,objects/seq_05_switch_quantity1_09.xml +w2_b2,6,Switch,1,Switch_Quantity1_10,1_1,70,120,"(2, 4, 6)",40,,objects/seq_06_switch_quantity1_10.xml +w2_b2,7,Switch,1,Switch_Quantity1_11,1_1,10,120,"(2, 4, 7)",41,,objects/seq_07_switch_quantity1_11.xml +w2_b2,8,Switch,1,Switch_Quantity1_12,1_1,-50,120,"(2, 4, 8)",42,,objects/seq_08_switch_quantity1_12.xml +w2_b2,9,Switch,1,Switch_Quantity1_13,1_1,-110,120,"(2, 4, 9)",43,,objects/seq_09_switch_quantity1_13.xml +w2_b2,10,Switch,1,Switch_Quantity1_14,1_1,-170,120,"(2, 4, 9)",44,,objects/seq_10_switch_quantity1_14.xml +w2_b2,11,Knob,1,Knob_Quantity1_04,1_1,-230,120,"(2, 4, 10)",45,厚30mm,objects/seq_11_knob_quantity1_04.xml +w2_b2,12,Switch,1,Switch_Quantity1_15,1_1,-290,120,"(2, 4, 11)",46,厚9mm,objects/seq_12_switch_quantity1_15.xml +w2_b2,13,Switch,1,Switch_Quantity1_16,1_1,-350,120,"(2, 4, 12)",47,厚15mm,objects/seq_13_switch_quantity1_16.xml +w2_b2,14,Switch,1,Switch_Quantity1_17,1_1,350,0,"(2, 5, 1)",48,,objects/seq_14_switch_quantity1_17.xml +w2_b2,15,Switch,1,Switch_Quantity1_18,1_1,296,0,"(2, 5, 2)",49,,objects/seq_15_switch_quantity1_18.xml +w2_b2,16,Switch,1,Switch_Quantity1_19,1_1,242,0,"(2, 5, 3)",50,,objects/seq_16_switch_quantity1_19.xml +w2_b2,17,Switch,1,Switch_Quantity1_20,1_1,188,0,"(2, 5, 4)",51,,objects/seq_17_switch_quantity1_20.xml +w2_b2,18,Switch,1,Switch_Quantity1_21,1_1,134,0,"(2, 5, 5)",52,,objects/seq_18_switch_quantity1_21.xml +w2_b2,19,Switch,1,Switch_Quantity1_22,1_1,70,0,"(2, 5, 6)",53,,objects/seq_19_switch_quantity1_22.xml +w2_b2,20,Stop,1,Stop_Quantity1_1,1_1,-70,0,"(2, 5, 8)",54,,objects/seq_20_stop_quantity1_1.xml +w2_b2,21,Switch,1,Switch_Quantity1_23,1_1,-140,0,"(2, 5, 9)",55,直径2.1,objects/seq_21_switch_quantity1_23.xml +w2_b2,22,Switch,1,Switch_Quantity1_24,1_1,-210,0,"(2, 5, 10)",56,,objects/seq_22_switch_quantity1_24.xml +w2_b2,23,Switch,1,Switch_Quantity1_25,1_1,-280,0,"(2, 5, 11)",57,,objects/seq_23_switch_quantity1_25.xml +w2_b2,24,Stop,1,Stop_Quantity1_2,1_1,-350,0,"(2, 5, 12)",58,厚20mm,objects/seq_24_stop_quantity1_2.xml +w2_b2,25,Switch,1,Switch_Quantity1_26,1_1,350,-120,"(2, 6, 1)",59,3*2.5,objects/seq_25_switch_quantity1_26.xml +w2_b2,26,Switch,1,Switch_Quantity1_27,1_1,285,-120,"(2, 6, 2)",60,,objects/seq_26_switch_quantity1_27.xml +w2_b2,27,Switch,1,Switch_Quantity1_28,1_1,220,-120,"(2, 6, 3)",61,,objects/seq_27_switch_quantity1_28.xml +w2_b2,28,Switch,1,Switch_Quantity1_29,1_1,155,-120,"(2, 6, 4)",62,,objects/seq_28_switch_quantity1_29.xml +w2_b2,29,Switch,1,Switch_Quantity1_30,1_1,90,-120,"(2, 6, 5)",63,,objects/seq_29_switch_quantity1_30.xml +w2_b2,30,Switch,1,Switch_Quantity1_31,1_1,25,-120,"(2, 6, 6)",64,,objects/seq_30_switch_quantity1_31.xml +w2_b2,31,Switch,1,Switch_Quantity1_32,1_1,-43.2,-120,"(2, 6, 7)",65,2.2*1.7,objects/seq_31_switch_quantity1_32.xml +w2_b2,32,Switch,1,Switch_Quantity1_33,1_1,-96.2,-120,"(2, 6, 8)",66,,objects/seq_32_switch_quantity1_33.xml +w2_b2,33,Switch,1,Switch_Quantity1_34,1_1,-149.2,-120,"(2, 6, 9)",67,2*1.5,objects/seq_33_switch_quantity1_34.xml +w2_b2,34,Switch,1,Switch_Quantity1_35,1_1,-202.2,-120,"(2, 6, 10)",68,厚6mm,objects/seq_34_switch_quantity1_35.xml +w2_b2,35,,,,,-255.2,-120,"(2, 6, 11)",,,objects/seq_35_unknown.xml +w2_b2,36,,,,,-308.2,-120,"(2, 6, 12)",,,objects/seq_36_unknown.xml +w2_b2,37,,,,,-361.2,-120,"(2, 6, 13)",,,objects/seq_37_unknown.xml diff --git a/examples/tune_randomization_extremes.py b/examples/tune_randomization_extremes.py index 949a8e1..cdca066 100644 --- a/examples/tune_randomization_extremes.py +++ b/examples/tune_randomization_extremes.py @@ -471,13 +471,24 @@ def _apply_case(self, case: ExtremeCase) -> None: ) target.apply_pose(compose_pose(base_world, sampled_in_base)) else: + base_pose = self._resolve_base_pose(target) target.apply_pose( _with_offsets( - target.get_default_pose(), + base_pose, offsets, target.rand_range, ) ) + + def _resolve_base_pose(self, target: RandomizationTarget) -> PoseState: + reference = target.rand_range.reference + if isinstance(reference, RandomizationReference): + return target.get_default_pose() + if reference in self.backend.object_handlers: + return self.backend.object_handlers[reference].get_pose() + if reference in self.backend.operator_handlers: + return self.backend.operator_handlers[reference].get_end_effector_pose() + return target.get_default_pose() self.env.refresh_viewer() self.case_var.set(case.name) self.desc_var.set(case.description)