mirror of
https://github.com/PotentiaRobotics/Fusion2PyBullet-Redux.git
synced 2025-04-09 14:50:17 -04:00
181 lines
6.5 KiB
Python
181 lines
6.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Export Link infos to XML from Fusion 360
|
|
|
|
@syuntoku
|
|
@yanshil
|
|
"""
|
|
|
|
import adsk, re
|
|
from xml.etree.ElementTree import Element, SubElement
|
|
from ..utils import utils
|
|
|
|
class Link:
|
|
|
|
def __init__(self, name, xyz, center_of_mass, repo, mass, inertia_tensor):
|
|
"""
|
|
Parameters
|
|
----------
|
|
name: str
|
|
name of the link
|
|
xyz: [x, y, z]
|
|
coordinate for the visual and collision
|
|
center_of_mass: [x, y, z]
|
|
coordinate for the center of mass
|
|
link_xml: str
|
|
generated xml describing about the link
|
|
repo: str
|
|
the name of the repository to save the xml file
|
|
mass: float
|
|
mass of the link
|
|
inertia_tensor: [ixx, iyy, izz, ixy, iyz, ixz]
|
|
tensor of the inertia
|
|
"""
|
|
self.name = name
|
|
# xyz for visual
|
|
self.xyz = [-_ for _ in xyz] # reverse the sign of xyz
|
|
# xyz for center of mass
|
|
self.center_of_mass = center_of_mass
|
|
self.link_xml = None
|
|
self.repo = repo
|
|
self.mass = mass
|
|
self.inertia_tensor = inertia_tensor
|
|
|
|
def make_link_xml(self):
|
|
"""
|
|
Generate the link_xml and hold it by self.link_xml
|
|
"""
|
|
|
|
link = Element('link')
|
|
link.attrib = {'name':self.name}
|
|
|
|
#inertial
|
|
inertial = SubElement(link, 'inertial')
|
|
origin_i = SubElement(inertial, 'origin')
|
|
origin_i.attrib = {'xyz':' '.join([str(_) for _ in self.center_of_mass]), 'rpy':'0 0 0'}
|
|
mass = SubElement(inertial, 'mass')
|
|
mass.attrib = {'value':str(self.mass)}
|
|
inertia = SubElement(inertial, 'inertia')
|
|
inertia.attrib = \
|
|
{'ixx':str(self.inertia_tensor[0]), 'iyy':str(self.inertia_tensor[1]),\
|
|
'izz':str(self.inertia_tensor[2]), 'ixy':str(self.inertia_tensor[3]),\
|
|
'iyz':str(self.inertia_tensor[4]), 'ixz':str(self.inertia_tensor[5])}
|
|
|
|
# visual
|
|
visual = SubElement(link, 'visual')
|
|
origin_v = SubElement(visual, 'origin')
|
|
origin_v.attrib = {'xyz':' '.join([str(_) for _ in self.xyz]), 'rpy':'0 0 0'}
|
|
geometry_v = SubElement(visual, 'geometry')
|
|
mesh_v = SubElement(geometry_v, 'mesh')
|
|
mesh_v.attrib = {'filename': self.repo + self.name + '.stl','scale':'0.001 0.001 0.001'} ## scale = 0.001 means mm to m. Modify it according if using another unit
|
|
material = SubElement(visual, 'material')
|
|
material.attrib = {'name':'silver'}
|
|
|
|
# collision
|
|
collision = SubElement(link, 'collision')
|
|
origin_c = SubElement(collision, 'origin')
|
|
origin_c.attrib = {'xyz':' '.join([str(_) for _ in self.xyz]), 'rpy':'0 0 0'}
|
|
geometry_c = SubElement(collision, 'geometry')
|
|
mesh_c = SubElement(geometry_c, 'mesh')
|
|
mesh_c.attrib = {'filename': self.repo + self.name + '.stl','scale':'0.001 0.001 0.001'} ## scale = 0.001 means mm to m. Modify it according if using another unit
|
|
material = SubElement(visual, 'material')
|
|
|
|
# print("\n".join(utils.prettify(link).split("\n")[1:]))
|
|
self.link_xml = "\n".join(utils.prettify(link).split("\n")[1:])
|
|
|
|
def make_inertial_dict(root, msg):
|
|
"""
|
|
Parameters
|
|
----------
|
|
root: adsk.fusion.Design.cast(product)
|
|
Root component
|
|
msg: str
|
|
Tell the status
|
|
|
|
Returns
|
|
----------
|
|
inertial_dict: {name:{mass, inertia, center_of_mass}}
|
|
|
|
msg: str
|
|
Tell the status
|
|
"""
|
|
# Get component properties.
|
|
allOccs = root.occurrences
|
|
inertial_dict = {}
|
|
|
|
for occs in allOccs:
|
|
# Skip the root component.
|
|
occs_dict = {}
|
|
prop = occs.getPhysicalProperties(adsk.fusion.CalculationAccuracy.VeryHighCalculationAccuracy)
|
|
|
|
occs_dict['name'] = re.sub('[ :()]', '_', occs.name)
|
|
|
|
mass = prop.mass # kg
|
|
occs_dict['mass'] = mass
|
|
center_of_mass = [_/100.0 for _ in prop.centerOfMass.asArray()] ## cm to m
|
|
occs_dict['center_of_mass'] = center_of_mass
|
|
|
|
# https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-ce341ee6-4490-11e5-b25b-f8b156d7cd97
|
|
(_, xx, yy, zz, xy, yz, xz) = prop.getXYZMomentsOfInertia()
|
|
moment_inertia_world = [_ / 10000.0 for _ in [xx, yy, zz, xy, yz, xz] ] ## kg / cm^2 -> kg/m^2
|
|
occs_dict['inertia'] = utils.origin2center_of_mass(moment_inertia_world, center_of_mass, mass)
|
|
|
|
if 'base_link' in occs.component.name:
|
|
inertial_dict['base_link'] = occs_dict
|
|
else:
|
|
inertial_dict[re.sub('[ :()]', '_', occs.name)] = occs_dict
|
|
|
|
return inertial_dict, msg
|
|
# def make_inertial_dict(root, msg):
|
|
# """
|
|
# Parameters
|
|
# ----------
|
|
# root: adsk.fusion.Design.cast(product)
|
|
# Root component
|
|
# msg: str
|
|
# Tell the status
|
|
|
|
# Returns
|
|
# ----------
|
|
# inertial_dict: {name:{mass, inertia, center_of_mass}}
|
|
|
|
# msg: str
|
|
# Tell the status
|
|
# """
|
|
# # Get ALL component properties.
|
|
# allOccs = root.allOccurrences
|
|
# inertial_dict = {}
|
|
|
|
# for occs in allOccs:
|
|
# # Skip the root component.
|
|
# occs_dict = {}
|
|
# prop = occs.getPhysicalProperties(adsk.fusion.CalculationAccuracy.VeryHighCalculationAccuracy)
|
|
|
|
|
|
|
|
# mass = prop.mass # kg
|
|
# occs_dict['mass'] = mass
|
|
# center_of_mass = [_/100.0 for _ in prop.centerOfMass.asArray()] ## cm to m
|
|
# occs_dict['center_of_mass'] = center_of_mass
|
|
|
|
# # https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-ce341ee6-4490-11e5-b25b-f8b156d7cd97
|
|
# (_, xx, yy, zz, xy, yz, xz) = prop.getXYZMomentsOfInertia()
|
|
# moment_inertia_world = [_ / 10000.0 for _ in [xx, yy, zz, xy, yz, xz] ] ## kg / cm^2 -> kg/m^2
|
|
# occs_dict['inertia'] = utils.origin2center_of_mass(moment_inertia_world, center_of_mass, mass)
|
|
|
|
# # if occs.component.name == 'base_link':
|
|
# # occs_dict['name'] = 'base_link'
|
|
# # inertial_dict['base_link'] = occs_dict
|
|
# # # print("Processing Base Link")
|
|
|
|
# if 'base_link' in occs.component.name:
|
|
# inertial_dict['base_link'] = occs_dict
|
|
# else:
|
|
# # occs_dict['name'] = re.sub('[ :()]', '_', occs.name)
|
|
# key = utils.get_valid_filename(occs.fullPathName)
|
|
# occs_dict['name'] = key
|
|
# inertial_dict[key] = occs_dict
|
|
|
|
# # print("Exporting link {}".format(occs_dict['name']))
|
|
|
|
# return inertial_dict, msg |