Skip to content

Commit

Permalink
[wip] Reduce model tree
Browse files Browse the repository at this point in the history
  • Loading branch information
flferretti committed Jan 5, 2024
1 parent 80c7757 commit aa092f5
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/adam/model/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,41 @@ def build(factory: ModelFactory, joints_name_list: List[str] = None) -> "Model":
floating_base=floating_base,
)

def reduce(self, joints_name_list: List[str]) -> "Model":
"""reduce the model to a subset of joints
Args:
joints_name_list (List[str]): the list of the joints to keep
Returns:
Model: the reduced model
"""

# check if the joints in the list are in the model
for joint_str in joints_name_list:
if joint_str not in self.joints.keys():
raise ValueError(
f"{joint_str} is not in the robot model. Check the joints_name_list"
)

tree = self.tree.reduce(joints_name_list)

# update nodes dict
links = {link.name: link for link in tree.graph}
frames = {frame.name: frame for frame in tree.graph}
joints = {joint.name: joint for joint in tree.graph}

return Model(
name=self.name,
links=links,
frames=frames,
joints=joints,
tree=tree,
NDoF=len(joints_name_list),
actuated_joints=joints_name_list,
floating_base=self.floating_base,
)

def get_joints_chain(self, root: str, target: str) -> List[Joint]:
"""generate the joints chains from a link to a link
Expand Down
23 changes: 23 additions & 0 deletions src/adam/model/std_factories/std_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,26 @@ def homogeneous(self) -> npt.ArrayLike:
self.inertial.origin.xyz,
self.inertial.origin.rpy,
)

def lump(self, other: "StdLink", relative_transform: npt.ArrayLike) -> "StdLink":
"""lump two links together
Args:
other (StdLink): the other link
relative_transform (npt.ArrayLike): the transform between the two links
Returns:
StdLink: the lumped link
"""
other_inertia = (
relative_transform.T @ other.spatial_inertia() @ relative_transform
)

# lump the inertial properties
lumped_mass = self.inertial.mass + other.inertial.mass
lumped_inertia = self.spatial_inertia() + other_inertia

self.mass = lumped_mass
self.inertia = lumped_inertia

return self
36 changes: 36 additions & 0 deletions src/adam/model/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,42 @@ def build_tree(links: List[Link], joints: List[Joint]) -> "Tree":
raise ValueError("The model has more than one root link")
return Tree(nodes, root_link[0])

def reduce(self, considered_joint_names: List[str]) -> "Tree":
"""reduces the tree to the considered joints
Args:
considered_joint_names (List[str]): the list of the considered joints
Returns:
Tree: the reduced tree
"""
new_graph = {}

# find the nodes that are not connected to the considered joints
nodes_to_lump = list(
{
node.name
for node in self.graph.values()
for joint in node.arcs
if joint.name not in considered_joint_names
}
)

# lump the inertial properties
for node in self.graph.values():
if node.name in nodes_to_lump:
lumped_node = node.parent.lump(
other=node.link,
relative_transform=node.parent_arc.spatial_transform(0),
)

# remove the node from the graph
self.graph.pop(node.name)

# TODO: WIP

return Tree(new_graph, self.root)

def print(self, root) -> str:
"""prints the tree
Expand Down

0 comments on commit aa092f5

Please sign in to comment.