Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reformat python code to pep8 standard #21

Merged
merged 1 commit into from
Jul 26, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions scripts/display_urdf
Original file line number Diff line number Diff line change
@@ -6,8 +6,10 @@ import argparse
from urdf_parser_py.urdf import URDF

parser = argparse.ArgumentParser(usage='Load an URDF file')
parser.add_argument('file', type=argparse.FileType('r'), nargs='?', default=None, help='File to load. Use - for stdin')
parser.add_argument('-o', '--output', type=argparse.FileType('w'), default=None, help='Dump file to XML')
parser.add_argument('file', type=argparse.FileType('r'), nargs='?',
default=None, help='File to load. Use - for stdin')
parser.add_argument('-o', '--output', type=argparse.FileType('w'),
default=None, help='Dump file to XML')
args = parser.parse_args()

if args.file is None:
195 changes: 103 additions & 92 deletions src/urdf_parser_py/sdf.py
Original file line number Diff line number Diff line change
@@ -5,117 +5,128 @@

xmlr.start_namespace('sdf')


class Pose(xmlr.Object):
def __init__(self, vec=None, extra=None):
self.xyz = None
self.rpy = None
if vec is not None:
assert isinstance(vec, list)
count = len(vec)
if len == 3:
xyz = vec
else:
self.from_vec(vec)
elif extra is not None:
assert xyz is None, "Cannot specify 6-length vector and 3-length vector"
assert len(extra) == 3, "Invalid length"
self.rpy = extra

def from_vec(self, vec):
assert len(vec) == 6, "Invalid length"
self.xyz = vec[:3]
self.rpy = vec[3:6]

def as_vec(self):
xyz = self.xyz if self.xyz else [0, 0, 0]
rpy = self.rpy if self.rpy else [0, 0, 0]
return xyz + rpy

def read_xml(self, node):
# Better way to do this? Define type?
vec = get_type('vector6').read_xml(node)
self.load_vec(vec)

def write_xml(self, node):
vec = self.as_vec()
get_type('vector6').write_xml(node, vec)

def check_valid(self):
assert self.xyz is not None or self.rpy is not None
def __init__(self, vec=None, extra=None):
self.xyz = None
self.rpy = None
if vec is not None:
assert isinstance(vec, list)
count = len(vec)
if len == 3:
xyz = vec
else:
self.from_vec(vec)
elif extra is not None:
assert xyz is None, "Cannot specify 6-length vector and 3-length vector" # noqa
assert len(extra) == 3, "Invalid length"
self.rpy = extra

def from_vec(self, vec):
assert len(vec) == 6, "Invalid length"
self.xyz = vec[:3]
self.rpy = vec[3:6]

def as_vec(self):
xyz = self.xyz if self.xyz else [0, 0, 0]
rpy = self.rpy if self.rpy else [0, 0, 0]
return xyz + rpy

def read_xml(self, node):
# Better way to do this? Define type?
vec = get_type('vector6').read_xml(node)
self.load_vec(vec)

def write_xml(self, node):
vec = self.as_vec()
get_type('vector6').write_xml(node, vec)

def check_valid(self):
assert self.xyz is not None or self.rpy is not None


name_attribute = xmlr.Attribute('name', str)
pose_element = xmlr.Element('pose', Pose, False)


class Entity(xmlr.Object):
def __init__(self, name = None, pose = None):
self.name = name
self.pose = pose
def __init__(self, name=None, pose=None):
self.name = name
self.pose = pose


xmlr.reflect(Entity, params = [
name_attribute,
pose_element
])
xmlr.reflect(Entity, params=[
name_attribute,
pose_element
])


class Inertia(xmlr.Object):
KEYS = ['ixx', 'ixy', 'ixz', 'iyy', 'iyz', 'izz']

def __init__(self, ixx=0.0, ixy=0.0, ixz=0.0, iyy=0.0, iyz=0.0, izz=0.0):
self.ixx = ixx
self.ixy = ixy
self.ixz = ixz
self.iyy = iyy
self.iyz = iyz
self.izz = izz

def to_matrix(self):
return [
[self.ixx, self.ixy, self.ixz],
[self.ixy, self.iyy, self.iyz],
[self.ixz, self.iyz, self.izz]]

xmlr.reflect(Inertia, params = [xmlr.Element(key, float) for key in Inertia.KEYS])
KEYS = ['ixx', 'ixy', 'ixz', 'iyy', 'iyz', 'izz']

def __init__(self, ixx=0.0, ixy=0.0, ixz=0.0, iyy=0.0, iyz=0.0, izz=0.0):
self.ixx = ixx
self.ixy = ixy
self.ixz = ixz
self.iyy = iyy
self.iyz = iyz
self.izz = izz

def to_matrix(self):
return [
[self.ixx, self.ixy, self.ixz],
[self.ixy, self.iyy, self.iyz],
[self.ixz, self.iyz, self.izz]]


xmlr.reflect(Inertia,
params=[xmlr.Element(key, float) for key in Inertia.KEYS])

# Pretty much copy-paste... Better method?
# Use multiple inheritance to separate the objects out so they are unique?


class Inertial(xmlr.Object):
def __init__(self, mass = 0.0, inertia = None, pose=None):
self.mass = mass
self.inertia = inertia
self.pose = pose
def __init__(self, mass=0.0, inertia=None, pose=None):
self.mass = mass
self.inertia = inertia
self.pose = pose

xmlr.reflect(Inertial, params = [
xmlr.Element('mass', float),
xmlr.Element('inertia', Inertia),
pose_element
])

xmlr.reflect(Inertial, params=[
xmlr.Element('mass', float),
xmlr.Element('inertia', Inertia),
pose_element
])


class Link(Entity):
def __init__(self, name = None, pose = None, inertial = None, kinematic = False):
Entity.__init__(self, name, pose)
self.inertial = inertial
self.kinematic = kinematic
def __init__(self, name=None, pose=None, inertial=None, kinematic=False):
Entity.__init__(self, name, pose)
self.inertial = inertial
self.kinematic = kinematic


xmlr.reflect(Link, parent_cls = Entity, params = [
xmlr.Element('inertial', Inertial),
xmlr.Attribute('kinematic', bool, False),
xmlr.AggregateElement('visual', Visual, var = 'visuals'),
xmlr.AggregateElement('collision', Collision, var = 'collisions')
])
xmlr.reflect(Link, parent_cls=Entity, params=[
xmlr.Element('inertial', Inertial),
xmlr.Attribute('kinematic', bool, False),
xmlr.AggregateElement('visual', Visual, var='visuals'),
xmlr.AggregateElement('collision', Collision, var='collisions')
])


class Model(Entity):
def __init__(self, name = None, pose=None):
Entity.__init__(self, name, pose)
self.links = []
self.joints = []
self.plugins = []

xmlr.reflect(Model, parent_cls = Entity, params = [
xmlr.AggregateElement('link', Link, var = 'links'),
xmlr.AggregateElement('joint', Joint, var = 'joints'),
xmlr.AggregateElement('plugin', Plugin, var = 'plugins')
])

xmlr.end_namespace('sdf')
def __init__(self, name=None, pose=None):
Entity.__init__(self, name, pose)
self.links = []
self.joints = []
self.plugins = []


xmlr.reflect(Model, parent_cls=Entity, params=[
xmlr.AggregateElement('link', Link, var='links'),
xmlr.AggregateElement('joint', Joint, var='joints'),
xmlr.AggregateElement('plugin', Plugin, var='plugins')
])

xmlr.end_namespace('sdf')
807 changes: 426 additions & 381 deletions src/urdf_parser_py/urdf.py

Large diffs are not rendered by default.

40 changes: 26 additions & 14 deletions src/urdf_parser_py/xml_reflection/basics.py
Original file line number Diff line number Diff line change
@@ -7,45 +7,54 @@
# @todo Do not use this?
from xml.etree.ElementTree import ElementTree

def xml_string(rootXml, addHeader = True):

def xml_string(rootXml, addHeader=True):
# Meh
xmlString = etree.tostring(rootXml, pretty_print = True)
xmlString = etree.tostring(rootXml, pretty_print=True)
if addHeader:
xmlString = '<?xml version="1.0"?>\n' + xmlString
return xmlString


def dict_sub(obj, keys):
return dict((key, obj[key]) for key in keys)


def node_add(doc, sub):
if sub is None:
return None
if type(sub) == str:
return etree.SubElement(doc, sub)
elif isinstance(sub, etree._Element):
doc.append(sub) # This screws up the rest of the tree for prettyprint...
doc.append(sub) # This screws up the rest of the tree for prettyprint
return sub
else:
raise Exception('Invalid sub value')


def pfloat(x):
return str(x).rstrip('.')
return str(x).rstrip('.')


def xml_children(node):
children = node.getchildren()

def predicate(node):
return not isinstance(node, etree._Comment)
return list(filter(predicate, children))


def isstring(obj):
try:
return isinstance(obj, basestring)
except NameError:
return isinstance(obj, str)


def to_yaml(obj):
""" Simplify yaml representation for pretty printing """
# Is there a better way to do this by adding a representation with yaml.Dumper?
# Is there a better way to do this by adding a representation with
# yaml.Dumper?
# Ordered dict: http://pyyaml.org/ticket/29#comment:11
if obj is None or isstring(obj):
out = str(obj)
@@ -54,7 +63,7 @@ def to_yaml(obj):
elif hasattr(obj, 'to_yaml'):
out = obj.to_yaml()
elif isinstance(obj, etree._Element):
out = etree.tostring(obj, pretty_print = True)
out = etree.tostring(obj, pretty_print=True)
elif type(obj) == dict:
out = {}
for (var, value) in obj.items():
@@ -68,14 +77,17 @@ def to_yaml(obj):
out = str(obj)
return out


class SelectiveReflection(object):
def get_refl_vars(self):
return list(vars(self).keys())
def get_refl_vars(self):
return list(vars(self).keys())


class YamlReflection(SelectiveReflection):
def to_yaml(self):
raw = dict((var, getattr(self, var)) for var in self.get_refl_vars())
return to_yaml(raw)

def __str__(self):
return yaml.dump(self.to_yaml()).rstrip() # Good idea? Will it remove other important things?
def to_yaml(self):
raw = dict((var, getattr(self, var)) for var in self.get_refl_vars())
return to_yaml(raw)

def __str__(self):
# Good idea? Will it remove other important things?
return yaml.dump(self.to_yaml()).rstrip()
995 changes: 525 additions & 470 deletions src/urdf_parser_py/xml_reflection/core.py

Large diffs are not rendered by default.

15 changes: 9 additions & 6 deletions test/test_urdf.py
Original file line number Diff line number Diff line change
@@ -7,15 +7,18 @@

# Add path to import xml_matching
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '.')))
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../src')))
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__),
'../src')))

from xml.dom import minidom # noqa
from xml_matching import xml_matches # noqa
from urdf_parser_py import urdf # noqa

from xml.dom import minidom
from xml_matching import xml_matches
from urdf_parser_py import urdf

class ParseException(Exception):
pass


class TestURDFParser(unittest.TestCase):
@mock.patch('urdf_parser_py.xml_reflection.on_error',
mock.Mock(side_effect=ParseException))
@@ -175,8 +178,8 @@ def test_robot_link_defaults_xyz_set(self):
robot = self.parse(xml)
origin = robot.links[0].inertial.origin
self.assertEquals(origin.xyz, [1, 2, 3])
self.assertEquals(origin.rpy, [0 ,0, 0])
self.assertEquals(origin.rpy, [0, 0, 0])


if __name__ == '__main__':
unittest.main()
30 changes: 18 additions & 12 deletions test/xml_matching.py
Original file line number Diff line number Diff line change
@@ -5,26 +5,27 @@
# regex to match whitespace
whitespace = re.compile(r'\s+')


def all_attributes_match(a, b):
if len(a.attributes) != len(b.attributes):
print("Different number of attributes")
return False
a_atts = [(a.attributes.item(i).name, a.attributes.item(i).value) for i in range(len(a.attributes))]
b_atts = [(b.attributes.item(i).name, b.attributes.item(i).value) for i in range(len(b.attributes))]
a_atts = [(a.attributes.item(i).name, a.attributes.item(i).value) for i in range(len(a.attributes))] # noqa
b_atts = [(b.attributes.item(i).name, b.attributes.item(i).value) for i in range(len(b.attributes))] # noqa
a_atts.sort()
b_atts.sort()

for i in range(len(a_atts)):
if a_atts[i][0] != b_atts[i][0]:
print("Different attribute names: %s and %s" % (a_atts[i][0], b_atts[i][0]))
print("Different attribute names: %s and %s" % (a_atts[i][0], b_atts[i][0])) # noqa
return False
try:
if abs(float(a_atts[i][1]) - float(b_atts[i][1])) > 1.0e-9:
print("Different attribute values: %s and %s" % (a_atts[i][1], b_atts[i][1]))
print("Different attribute values: %s and %s" % (a_atts[i][1], b_atts[i][1])) # noqa
return False
except ValueError: # Attribute values aren't numeric
if a_atts[i][1] != b_atts[i][1]:
print("Different attribute values: %s and %s" % (a_atts[i][1], b_atts[i][1]))
print("Different attribute values: %s and %s" % (a_atts[i][1], b_atts[i][1])) # noqa
return False

return True
@@ -33,7 +34,8 @@ def all_attributes_match(a, b):
def text_matches(a, b):
a_norm = whitespace.sub(' ', a)
b_norm = whitespace.sub(' ', b)
if a_norm.strip() == b_norm.strip(): return True
if a_norm.strip() == b_norm.strip():
return True
print("Different text values: '%s' and '%s'" % (a, b))
return False

@@ -73,27 +75,31 @@ def nodes_match(a, b, ignore_nodes):
# we could have several text nodes in a row, due to replacements
while (a and
((a.nodeType in ignore_nodes) or
(a.nodeType == xml.dom.Node.TEXT_NODE and whitespace.sub('', a.data) == ""))):
(a.nodeType == xml.dom.Node.TEXT_NODE and whitespace.sub('', a.data) == ""))): # noqa
a = a.nextSibling
while (b and
((b.nodeType in ignore_nodes) or
(b.nodeType == xml.dom.Node.TEXT_NODE and whitespace.sub('', b.data) == ""))):
(b.nodeType == xml.dom.Node.TEXT_NODE and whitespace.sub('', b.data) == ""))): # noqa
b = b.nextSibling

if not nodes_match(a, b, ignore_nodes):
return False

if a: a = a.nextSibling
if b: b = b.nextSibling
if a:
a = a.nextSibling
if b:
b = b.nextSibling

return True


def xml_matches(a, b, ignore_nodes=[]):
if isinstance(a, str):
return xml_matches(xml.dom.minidom.parseString(a).documentElement, b, ignore_nodes)
return xml_matches(xml.dom.minidom.parseString(a).documentElement, b,
ignore_nodes)
if isinstance(b, str):
return xml_matches(a, xml.dom.minidom.parseString(b).documentElement, ignore_nodes)
return xml_matches(a, xml.dom.minidom.parseString(b).documentElement,
ignore_nodes)
if a.nodeType == xml.dom.Node.DOCUMENT_NODE:
return xml_matches(a.documentElement, b, ignore_nodes)
if b.nodeType == xml.dom.Node.DOCUMENT_NODE: