Source code for compas_fab.robots.tool


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import json

from compas.robots import Geometry
from compas.robots import ToolModel

from compas_fab.robots.planning_scene import AttachedCollisionMesh
from compas_fab.robots.planning_scene import CollisionMesh


__all__ = [
    'Tool'
]


[docs]class Tool(object): """Represents a tool to be attached to the robot's flange. Attributes ---------- visual : :class:`compas.datastructures.Mesh` The visual mesh of the tool. frame_in_tool0_frame : :class:`compas.geometry.Frame` The frame of the tool in tool0 frame. collision : :class:`compas.datastructures.Mesh` The collision mesh representation of the tool. name : :obj:`str` The name of the `Tool`. Defaults to 'attached_tool'. link_name : :obj:`str` The name of the `Link` to which the tool is attached. Defaults to ``None``. Examples -------- >>> mesh = Mesh.from_stl(compas_fab.get('planning_scene/cone.stl')) >>> frame = Frame([0.14, 0, 0], [0, 1, 0], [0, 0, 1]) >>> tool = Tool(mesh, frame) """
[docs] def __init__(self, visual, frame_in_tool0_frame, collision=None, name="attached_tool", link_name=None): self.tool_model = ToolModel(visual, frame_in_tool0_frame, collision, name, link_name)
[docs] @classmethod def from_tool_model(cls, tool_model): tool = cls(None, None) tool.tool_model = tool_model return tool
@property def attached_collision_meshes(self): acms = [] for link in self.tool_model.iter_links(): for i, item in enumerate(link.collision): meshes = Geometry._get_item_meshes(item) for mesh in meshes: collision_mesh_name = '{}_collision_{}'.format(link.name, i) collision_mesh = CollisionMesh(mesh, collision_mesh_name) attached_collision_mesh = AttachedCollisionMesh(collision_mesh, self.link_name, [self.link_name]) acms.append(attached_collision_mesh) return acms @property def name(self): return self.tool_model.name @property def link_name(self): return self.tool_model.link_name @link_name.setter def link_name(self, link_name): self.tool_model.link_name = link_name @property def frame(self): return self.tool_model.frame @frame.setter def frame(self, frame): self.tool_model.frame = frame @property def data(self): """Returns the data dictionary that represents the tool. Returns ------- :obj:`dict` The frame data. """ data = self.tool_model.data return data @data.setter def data(self, data): self.tool_model.data = data
[docs] @classmethod def from_data(cls, data): """Construct a `Tool` from its data representation. Parameters ---------- data : :obj:`dict` The data dictionary. Returns ------- :class:`Tool` The constructed `Tool`. Examples -------- >>> mesh = Mesh.from_stl(compas_fab.get('planning_scene/cone.stl')) >>> frame = Frame([0.14, 0, 0], [0, 1, 0], [0, 0, 1]) >>> data = {'visual': mesh.data, 'frame': frame.data} >>> tool = Tool.from_data(data) """ tool = cls(None, None) tool.data = data return tool
[docs] @classmethod def from_json(cls, filepath): """Construct a `Tool` from the data contained in a JSON file. Parameters ---------- filepath : str Path to the file containing the data. Returns ------- :class:`Tool` The tool. Examples -------- >>> filepath = os.path.join(compas_fab.DATA, "planning_scene", "cone_tool.json") >>> tool = Tool.from_json(filepath) """ with open(filepath, 'r') as f: data = json.load(f) return cls.from_data(data)
[docs] def to_json(self, filepath): """Serialise the data dictionary representing the tool to JSON and store in a file. Parameters ---------- filepath : :obj:`str` Path to the file. Returns ------- None Examples -------- >>> mesh = Mesh.from_stl(compas_fab.get('planning_scene/cone.stl')) >>> frame = Frame([0.14, 0, 0], [0, 1, 0], [0, 0, 1]) >>> tool = Tool(mesh, frame) >>> filepath = os.path.join(compas_fab.DATA, "planning_scene", "cone_tool.json") >>> tool.to_json(filepath) """ with open(filepath, 'w') as f: json.dump(self.data, f, indent=4, sort_keys=True)
[docs] def from_tcf_to_t0cf(self, frames_tcf): """Converts a list of frames at the robot's tool tip (tcf frame) to frames at the robot's flange (tool0 frame). Parameters ---------- frames_tcf : :obj:`list` of :class:`compas.geometry.Frame` Frames (in WCF) at the robot's tool tip (tcf). Returns ------- :obj:`list` of :class:`compas.geometry.Frame` Frames (in WCF) at the robot's flange (tool0). Examples -------- >>> mesh = Mesh.from_stl(compas_fab.get('planning_scene/cone.stl')) >>> frame = Frame([0.14, 0, 0], [0, 1, 0], [0, 0, 1]) >>> tool = Tool(mesh, frame) >>> frames_tcf = [Frame((-0.309, -0.046, -0.266), (0.276, 0.926, -0.256), (0.879, -0.136, 0.456))] >>> tool.from_tcf_to_t0cf(frames_tcf) [Frame(Point(-0.363, 0.003, -0.147), Vector(0.388, -0.351, -0.852), Vector(0.276, 0.926, -0.256))] """ return self.tool_model.from_tcf_to_t0cf(frames_tcf)
[docs] def from_t0cf_to_tcf(self, frames_t0cf): """Converts frames at the robot's flange (tool0 frame) to frames at the robot's tool tip (tcf frame). Parameters ---------- frames_t0cf : :obj:`list` of :class:`compas.geometry.Frame` Frames (in WCF) at the robot's flange (tool0). Returns ------- :obj:`list` of :class:`compas.geometry.Frame` Frames (in WCF) at the robot's tool tip (tcf). Examples -------- >>> mesh = Mesh.from_stl(compas_fab.get('planning_scene/cone.stl')) >>> frame = Frame([0.14, 0, 0], [0, 1, 0], [0, 0, 1]) >>> tool = Tool(mesh, frame) >>> frames_t0cf = [Frame((-0.363, 0.003, -0.147), (0.388, -0.351, -0.852), (0.276, 0.926, -0.256))] >>> tool.from_t0cf_to_tcf(frames_t0cf) [Frame(Point(-0.309, -0.046, -0.266), Vector(0.276, 0.926, -0.256), Vector(0.879, -0.136, 0.456))] """ return self.tool_model.from_t0cf_to_tcf(frames_t0cf)