Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 71 additions & 6 deletions mujoco_urdf_loader/mjcf_fcn.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ def add_position_actuator(

return mjcf


def add_torque_actuator(
mjcf: ET.Element,
joint: str,
Expand Down Expand Up @@ -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,
Copy link
Copy Markdown
Contributor

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!

) -> ET.Element:
"""Add a joint equality constraint between two joints.

Expand Down Expand Up @@ -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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the same style used in add_sites_eq?


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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree


return mjcf
Loading