Skip to content

Commit aa092f5

Browse files
committed
[wip] Reduce model tree
1 parent 80c7757 commit aa092f5

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed

src/adam/model/model.py

+35
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,41 @@ def build(factory: ModelFactory, joints_name_list: List[str] = None) -> "Model":
8080
floating_base=floating_base,
8181
)
8282

83+
def reduce(self, joints_name_list: List[str]) -> "Model":
84+
"""reduce the model to a subset of joints
85+
86+
Args:
87+
joints_name_list (List[str]): the list of the joints to keep
88+
89+
Returns:
90+
Model: the reduced model
91+
"""
92+
93+
# check if the joints in the list are in the model
94+
for joint_str in joints_name_list:
95+
if joint_str not in self.joints.keys():
96+
raise ValueError(
97+
f"{joint_str} is not in the robot model. Check the joints_name_list"
98+
)
99+
100+
tree = self.tree.reduce(joints_name_list)
101+
102+
# update nodes dict
103+
links = {link.name: link for link in tree.graph}
104+
frames = {frame.name: frame for frame in tree.graph}
105+
joints = {joint.name: joint for joint in tree.graph}
106+
107+
return Model(
108+
name=self.name,
109+
links=links,
110+
frames=frames,
111+
joints=joints,
112+
tree=tree,
113+
NDoF=len(joints_name_list),
114+
actuated_joints=joints_name_list,
115+
floating_base=self.floating_base,
116+
)
117+
83118
def get_joints_chain(self, root: str, target: str) -> List[Joint]:
84119
"""generate the joints chains from a link to a link
85120

src/adam/model/std_factories/std_link.py

+23
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,26 @@ def homogeneous(self) -> npt.ArrayLike:
4444
self.inertial.origin.xyz,
4545
self.inertial.origin.rpy,
4646
)
47+
48+
def lump(self, other: "StdLink", relative_transform: npt.ArrayLike) -> "StdLink":
49+
"""lump two links together
50+
51+
Args:
52+
other (StdLink): the other link
53+
relative_transform (npt.ArrayLike): the transform between the two links
54+
55+
Returns:
56+
StdLink: the lumped link
57+
"""
58+
other_inertia = (
59+
relative_transform.T @ other.spatial_inertia() @ relative_transform
60+
)
61+
62+
# lump the inertial properties
63+
lumped_mass = self.inertial.mass + other.inertial.mass
64+
lumped_inertia = self.spatial_inertia() + other_inertia
65+
66+
self.mass = lumped_mass
67+
self.inertia = lumped_inertia
68+
69+
return self

src/adam/model/tree.py

+36
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,42 @@ def build_tree(links: List[Link], joints: List[Joint]) -> "Tree":
7171
raise ValueError("The model has more than one root link")
7272
return Tree(nodes, root_link[0])
7373

74+
def reduce(self, considered_joint_names: List[str]) -> "Tree":
75+
"""reduces the tree to the considered joints
76+
77+
Args:
78+
considered_joint_names (List[str]): the list of the considered joints
79+
80+
Returns:
81+
Tree: the reduced tree
82+
"""
83+
new_graph = {}
84+
85+
# find the nodes that are not connected to the considered joints
86+
nodes_to_lump = list(
87+
{
88+
node.name
89+
for node in self.graph.values()
90+
for joint in node.arcs
91+
if joint.name not in considered_joint_names
92+
}
93+
)
94+
95+
# lump the inertial properties
96+
for node in self.graph.values():
97+
if node.name in nodes_to_lump:
98+
lumped_node = node.parent.lump(
99+
other=node.link,
100+
relative_transform=node.parent_arc.spatial_transform(0),
101+
)
102+
103+
# remove the node from the graph
104+
self.graph.pop(node.name)
105+
106+
# TODO: WIP
107+
108+
return Tree(new_graph, self.root)
109+
74110
def print(self, root) -> str:
75111
"""prints the tree
76112

0 commit comments

Comments
 (0)