-
Notifications
You must be signed in to change notification settings - Fork 2
Add function to create equality constraints between MJCF sites #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -86,6 +86,7 @@ def add_position_actuator( | |
|
|
||
| return mjcf | ||
|
|
||
|
|
||
| def add_torque_actuator( | ||
| mjcf: ET.Element, | ||
| joint: str, | ||
|
|
@@ -177,12 +178,12 @@ def add_joint_vel_sensor(mjcf: ET.Element, joint: str, name: str = None) -> ET.E | |
|
|
||
|
|
||
| def add_joint_eq( | ||
| mjcf: ET.Element, | ||
| joint1: str, | ||
| joint2: str, | ||
| name: str = None, | ||
| multiplier: float = 1.0, | ||
| offset: float = 0.0 | ||
| mjcf: ET.Element, | ||
| joint1: str, | ||
| joint2: str, | ||
| name: str = None, | ||
| multiplier: float = 1.0, | ||
| offset: float = 0.0, | ||
| ) -> ET.Element: | ||
| """Add a joint equality constraint between two joints. | ||
|
|
||
|
|
@@ -411,3 +412,67 @@ def add_sphere( | |
| geom.set("mass", f"{mass}") | ||
|
|
||
| return mjcf | ||
|
|
||
|
|
||
| def add_equality_constraints_for_sites( | ||
| mjcf: ET.Element, site_pairs: List[tuple], constraint_type: str = "connect" | ||
| ) -> ET.Element: | ||
|
Comment on lines
+417
to
+419
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, can we add a small test that adds an equality between sites in a minimal model (like a four bar linkage or something similar made by spherical joints) and check if mujoco parse it correctly? |
||
| """ | ||
| Add equality constraints between pairs of sites in MJCF. | ||
|
Comment on lines
+420
to
+421
|
||
|
|
||
| Args: | ||
| mjcf (ET.Element): The MJCF file as ElementTree. | ||
| site_pairs (List[tuple]): List of tuples with (site1_name, site2_name) to connect. | ||
| constraint_type (str): Type of constraint - "connect" or "weld" (default: "connect"). | ||
|
|
||
| Returns: | ||
| ET.Element: The modified MJCF file. | ||
| """ | ||
| # Find or create the equality element | ||
| equality = mjcf.find("equality") | ||
|
|
||
| if equality is None: | ||
| equality = ET.SubElement(mjcf, "equality") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use the same style used in |
||
|
|
||
| for site1, site2 in site_pairs: | ||
| # Verify both sites exist | ||
| site1_elem = mjcf.find(f".//site[@name='{site1}']") | ||
| site2_elem = mjcf.find(f".//site[@name='{site2}']") | ||
|
|
||
|
Comment on lines
+436
to
+440
|
||
| if site1_elem is None: | ||
| raise ValueError(f"Site {site1} not found in MJCF") | ||
| if site2_elem is None: | ||
| raise ValueError(f"Site {site2} not found in MJCF") | ||
|
|
||
| # Create the equality constraint | ||
| if constraint_type == "connect": | ||
| # Connect constraint directly references sites (no anchor needed for sites) | ||
| constraint = ET.SubElement(equality, "connect") | ||
| constraint.set("site1", site1) | ||
| constraint.set("site2", site2) | ||
| elif constraint_type == "weld": | ||
| # Weld constraint references bodies | ||
| # Find parent bodies of the sites | ||
| body1 = None | ||
| body2 = None | ||
| for body in mjcf.findall(".//body"): | ||
| if body.find(f".//site[@name='{site1}']") is not None: | ||
| body1 = body.attrib.get("name") | ||
| if body.find(f".//site[@name='{site2}']") is not None: | ||
| body2 = body.attrib.get("name") | ||
|
|
||
|
Comment on lines
+452
to
+462
|
||
| if body1 is None or body2 is None: | ||
| raise ValueError( | ||
| f"Could not find parent bodies for sites {site1} and {site2}" | ||
| ) | ||
|
|
||
| constraint = ET.SubElement(equality, "weld") | ||
| constraint.set("body1", body1) | ||
| constraint.set("body2", body2) | ||
| else: | ||
| raise ValueError(f"Unknown constraint type: {constraint_type}") | ||
|
|
||
| print( | ||
| f"Created {constraint_type} equality constraint between {site1} and {site2}" | ||
| ) | ||
|
Comment on lines
+474
to
+476
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree |
||
|
|
||
| return mjcf | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove changes unrelated to the PR, thanks!