Source code for adam.model.model

import dataclasses
from typing import Dict, List

from adam.model.abc_factories import Joint, Link, ModelFactory
from adam.model.tree import Tree


@dataclasses.dataclass
[docs] class Model: """ Model class. It describes the robot using links and frames and their connectivity"""
[docs] name: str
[docs] frames: Dict[str, Link]
[docs] joints: Dict[str, Joint]
[docs] tree: Tree
[docs] NDoF: int
[docs] actuated_joints: List[str]
[docs] def __post_init__(self): """set the "length of the model as the number of links""" self.N = len(self.links)
@staticmethod
[docs] def build(factory: ModelFactory, joints_name_list: List[str] = None) -> "Model": """generates the model starting from the list of joints and the links-joints factory Args: factory (ModelFactory): the factory that generates the links and the joints, starting from a description (eg. urdf) joints_name_list (List[str]): the list of the actuated joints Returns: Model: the model describing the robot """ joints_list = factory.get_joints() links_list = factory.get_links() frames_list = factory.get_frames() # if the joints_name_list is None, set it to the list of all the joints that are not fixed if joints_name_list is None: joints_name_list = [ joint.name for joint in joints_list if joint.type != "fixed" ] print( f"joints_name_list is None. Setting it to the list of all the joints that are not fixed: {joints_name_list}" ) # check if the joints in the list are in the model for joint_str in joints_name_list: if joint_str not in [joint.name for joint in joints_list]: raise ValueError( f"{joint_str} is not in the robot model. Check the joints_name_list" ) # set idx to the actuated joints for [idx, joint_str] in enumerate(joints_name_list): for joint in joints_list: if joint.name == joint_str: joint.idx = idx tree = Tree.build_tree(links=links_list, joints=joints_list) # generate some useful dict joints: Dict[str, Joint] = {joint.name: joint for joint in joints_list} links: Dict[str, Link] = {link.name: link for link in links_list} frames: Dict[str, Link] = {frame.name: frame for frame in frames_list} return Model( name=factory.name, links=links, frames=frames, joints=joints, tree=tree, NDoF=len(joints_name_list), actuated_joints=joints_name_list, )
[docs] def get_joints_chain(self, root: str, target: str) -> List[Joint]: """generate the joints chains from a link to a link Args: root (str): the starting link target (str): the target link Returns: List[Joint]: the list of the joints """ if target not in list(self.links) and target not in list(self.frames): raise ValueError(f"{target} is not not in the robot model.") if target == root: return [] chain = [] current_node = [ joint for joint in self.joints.values() if joint.child == target ][0] chain.insert(0, current_node) while current_node.parent != root: current_node = [ joint for joint in self.joints.values() if joint.child == current_node.parent ][0] chain.insert(0, current_node) return chain
[docs] def get_total_mass(self) -> float: """total mass of the robot Returns: float: the total mass of the robot """ mass = 0.0 for item in self.links: link = self.links[item] mass += link.inertial.mass return mass
[docs] def print_table(self): """print the table that describes the connectivity between the elements. You need rich to use it """ try: from rich.console import Console from rich.table import Table except Exception: print("rich is not installed!") return console = Console() table = Table(show_header=True, header_style="bold red") table.add_column("Idx") table.add_column("Parent Link") table.add_column("Joint name") table.add_column("Child Link") table.add_column("Type") nodes = self.tree.graph j = 1 for item in nodes: if len(nodes[item].children) != 0: for arc in nodes[item].arcs: table.add_row(str(j), item, arc.name, arc.child, arc.type) j += 1 console.print(table)