German Larrain avatar German Larrain committed 9246d2d

docstrings: changed ''' to """; style homogeneization

Comments (0)

Files changed (23)

ars/app/__init__.py

 #===============================================================================
 
 	def select_next_joint(self):
-		'''
-		select next joint for future user actions
-		'''
+		"""select next joint for future user actions"""
 		print('select_next_joint has not been implemented yet')
 
 	def select_previous_joint(self):
-		'''
-		select previous joint for future user actions
-		'''
+		"""select previous joint for future user actions"""
 		print('select_previous_joint has not been implemented yet')
 
 	def add_force(self):
-		'''
-		add force to an already selected joint
-		'''
+		"""add force to an already selected joint"""
 		print('add_force has not been implemented yet')
 
 	def add_torque(self):
-		'''
-		add torque to an already selected joint
-		'''
+		"""add torque to an already selected joint"""
 		print('add_torque has not been fully implemented')
 
 	def inc_joint_vel(self):
-		'''
-		increment the velocity of an already selected joint
-		'''
+		"""increment the velocity of an already selected joint"""
 		print('inc_joint_vel has not been implemented yet')
 
 	def dec_joint_vel(self):
-		'''
-		decrement the velocity of an already selected joint
-		'''
+		"""decrement the velocity of an already selected joint"""
 		print('dec_joint_vel has not been implemented yet')
 
 	def inc_joint_pos(self):
-		'''
-		increment the position of an already selected joint
-		'''
+		"""increment the position of an already selected joint"""
 		print('inc_joint_pos has not been implemented yet')
 
 	def dec_joint_pos(self):
-		'''
-		decrement the position of an already selected joint
-		'''
+		"""decrement the position of an already selected joint"""
 		print('dec_joint_pos has not been implemented yet')
 
 
 
 
 class KeyPressActionMap(ActionMap):
-	'''
-	customize the behavior, knowing which strings mean existing keys or not, plus combinations (e.g. Ctrl+F1)
-	'''
+	"""
+	customize the behavior, knowing which strings mean existing keys or not,
+	plus combinations (e.g. Ctrl+F1)
+	"""
 	pass

ars/graphics/__init__.py

 		return self._actor
 
 class Body:
-	'''
+	"""
 	Abstract class. Not coupled (at all) with VTK or any other graphics library
-	'''
+	"""
 	__metaclass__ = ABCMeta
 
 	@abstractmethod
 		super(Trimesh, self).__init__(position, rotation)
 
 class Adapter:
-	'''
+	"""
 	Abstract class. Not coupled (at all) with VTK or any other graphics library
-	'''
+	"""
 	__metaclass__ = ABCMeta
 
 	@abstractmethod

ars/graphics/adapters.py

 
 class VtkAdapter(gp.Adapter):
 
-	''' Graphics adapter to the Visualization Toolkit (VTK) library '''
+	"""Graphics adapter to the Visualization Toolkit (VTK) library"""
 
 	def __init__(self):
 		super(VtkAdapter, self).__init__()
 		iren.GetRenderWindow().Render() # same as self.renWin.Render() ?
 
 	def _key_press_callback(self, obj, event):
-		'''
+		"""
 		obj: the vtkRenderWindowInteractor
 		event: "KeyPressEvent"
-		'''
+		"""
 
 		key = obj.GetKeySym().lower()
 		if self.on_key_press_parent_callback:
 
 	@staticmethod
 	def _create_transform_matrix(position, rotMatrix):
-		'''
+		"""
 		position: a 3-tuple
 		rotMatrix: a 9-tuple
-		'''
+		"""
 		t = mut.Transform(position, rotMatrix)
 		vtk_matrix = vtk.vtkMatrix4x4()
 		vtk_matrix.DeepCopy(t.get_long_tuple())
 		self._actor = coneActor
 
 class Sphere(VtkBody, gp.Sphere):
-	'''
-	VTK: sphere (represented by polygons) of specified radius centered at the origin.
-	The resolution (polygonal discretization) in both the latitude (phi) and longitude (theta)
-	directions can be specified.
-	'''
+	"""
+	VTK: sphere (represented by polygons) of specified radius centered at the
+	origin. The resolution (polygonal discretization) in both the latitude
+	(phi) and longitude (theta)	directions can be specified.
+	"""
 
 	def __init__(self, radius, center, rotation=None, phiResolution = 20, thetaResolution = 20):
 		super(Sphere, self).__init__(radius, center, rotation, phiResolution, thetaResolution)

ars/model/contrib/caster.py

 # @author: german
 
 class Caster:
-	'''
+	"""
 	classdocs
-	'''
+	"""
 
 
 	def __init__(self, params):
-		'''
+		"""
 		Constructor
-		'''
-		
+		"""

ars/model/contrib/ragdoll.py

 
 class RagDoll:
 
-	'''
-	RAGDOLL BODY DIMENSIONS
-	'''
+	#===========================================================================
+	# RAGDOLL BODY DIMENSIONS
+	#===========================================================================
 	UPPER_ARM_LEN = 0.30
 	FORE_ARM_LEN = 0.25
 	HAND_LEN = 0.13 # wrist to mid-fingers only
 	L_TOES_POS = mut.add3(L_ANKLE_POS, (0.0, 0.0, FOOT_LEN))
 
 	def __init__(self, world, space, offset=(0.0, 0.0, 0.0), density=1.0):
-		"""Creates a ragdoll of standard size at the given offset."""
+		"""Creates a ragdoll of standard size at the given offset"""
 
 		self.world = world
 		self.space = space

ars/model/geometry/shapes.py

 import ode
 
 class Shape:
-	'''
-	Encapsules a geometry object
-	'''
+	"""Encapsules a geometry object"""
 	__metaclass__ = ABCMeta
-	
+
 	@abstractmethod
 	def __init__(self):
 		self._inner_object = None
-		self._attached_body = None 
-	
+		self._attached_body = None
+
 	def attach_body(self, body):
 		self._inner_object.setBody(body.get_inner_object())
 		self._attached_body = body
-		
+
 	def get_inner_object(self):
 		return self._inner_object
-		
+
 	def get_attached_body(self):
 		return self._attached_body
 
 	__metaclass__ = ABCMeta
 
 class Trimesh(Shape):
-	
+
 	def __init__(self, space, vertices, faces, center):
 		tm_data = ode.TriMeshData()
 		tm_data.build(vertices, faces)
 		# do we need to save the data too?
 		self._inner_object = ode.GeomTriMesh(tm_data, space.get_inner_object())
 		self._inner_object.setPosition(center)
-	
+
 	@staticmethod
 	def get_heightfield_faces(num_x, num_z):
-		"""
-		Creates the faces corresponding to a heightfield size 'num_x' by 'num_z'.
-		Faces are triangular, so each is composed by 3 vertices.
-		"""
-		
+		"""Creates the faces corresponding to a heightfield size 'num_x' by
+		'num_z'. Faces are triangular, so each is composed by 3 vertices."""
+
 		# index of each square is calculated because it is needed to define faces
 		indices = []
-		
+
 		for x in range(num_x):
 			indices_x = []
 			for z in range(num_z):
 				indices_x.insert(z, num_z * x + z)
 			indices.insert(x, indices_x)
 
-		# faces = [(1a,1b,1c), (2a,2b,2c), ...] 
+		# faces = [(1a,1b,1c), (2a,2b,2c), ...]
 		faces = []
-		
+
 		for x in range(num_x - 1):
 			for z in range(num_z - 1):
-				
+
 				zero = indices[x][z] # top-left corner
 				one = indices[x][z + 1] # bottom-left
 				two = indices[x + 1][z] # top-right
 				three = indices[x + 1][z + 1] # bottom-right
-				
+
 				# there are two face types for each square
 				# contiguous squares must have different face types
-				face_type = zero 
+				face_type = zero
 				if num_z % 2 == 0:
 					face_type += 1
-				
+
 				# there are 2 faces per square
 				if face_type % 2 == 0:
 					face1 = (zero, three, two)
 				else:
 					face1 = (zero, one, two)
 					face2 = (one, three, two)
-				
+
 				faces.append(face1)
 				faces.append(face2)
 
 		return faces
-	
+
 	@staticmethod
 	def swap_faces_indices(faces):
-		"""
-		Faces had to change their indices to work with ODE. With the initial get_faces,
-		the normal to the triangle defined by the 3 vertices pointed (following the 
-		right-hand rule) downwards. Swapping the third with the first index, now the
-		triangle normal pointed upwards.
-		"""
-		
+		"""Faces had to change their indices to work with ODE. With the initial
+		get_faces, the normal to the triangle defined by the 3 vertices pointed
+		(following the right-hand rule) downwards. Swapping the third with the
+		first index, now the triangle normal pointed upwards."""
+
 		new_faces = []
 		for face in faces:
 			new_faces.append((face[2], face[1], face[0]))
 	#===========================================================================
 	# def attach_body(self, body):
 	#	raise Exception('Trimesh shapes are not yet allowed to have a body attached')
-	#	
+	#
 	# def get_attached_body(self):
 	#	raise Exception('Trimesh shapes are not yet allowed to have a body attached')
 	#===========================================================================
 
 
 class Box(Primitive):
-	'''
-	Box shape, aligned along the X, Y and Z axii by default.
-	'''
+	"""Box shape, aligned along the X, Y and Z axii by default"""
 	def __init__(self, space, size):
 		self._inner_object = ode.GeomBox(space.get_inner_object(), lengths=size)
 
 class Sphere(Primitive):
-	'''
-	Spherical shape.
-	'''
+	"""Spherical shape"""
 	def __init__(self, space, radius):
 		self._inner_object = ode.GeomSphere(space.get_inner_object(), radius)
 
 class Capsule(Primitive):
-	'''
-	Capsule shape, aligned along the Z-axis by default.
-	'''
+	"""Capsule shape, aligned along the Z-axis by default"""
 	def __init__(self, space, length, radius):
 		# GeomCCylinder != GeomCylinder
 		# GeomCCylinder: Capped Cylinder
 		self._inner_object = ode.GeomCCylinder(space.get_inner_object(), radius, length)
 
 class Cylinder(Primitive):
-	'''
-	Cylinder shape, aligned along the Z-axis by default.
-	'''
+	"""Cylinder shape, aligned along the Z-axis by default"""
 	def __init__(self, space, length, radius):
 		self._inner_object = ode.GeomCylinder(space.get_inner_object(), radius, length)
 
 class Plane(Primitive):
-	'''
-	Plane, different from a box.
-	'''
+	"""Plane, different from a box"""
 	def __init__(self, space, normal, dist):
 		self._inner_object = ode.GeomPlane(space.get_inner_object(), normal, dist)
 
 class Cone(Primitive):
-	'''
-	Cone.
-	'''
+	"""Cone"""
 	def __init__(self):
 		raise Exception("Not available in ODE")

ars/model/robot/joints.py

 import ars.exceptions as exc
 
 class Joint:
-	'''
+	"""
 	Abstract class. Not coupled (at all) with ODE or any other collision library/engine
-	'''
+	"""
 	__metaclass__ = ABCMeta
-	
+
 	@abstractmethod
 	def __init__(self, world, inner_joint, body1=None, body2=None):
 		self._world = world
 		self._inner_joint = inner_joint
 		self._body1 = body1
 		self._body2 = body2
-	
+
 	def get_body1(self):
 		return self._body1
-	
+
 	def get_body2(self):
 		return self._body2
 
 			inner_joint = ode.FixedJoint(world)
 			inner_joint.attach(body1.get_inner_object(), body2.get_inner_object())
 			inner_joint.setFixed()
-			
+
 			super(Fixed, self).__init__(world, inner_joint, body1, body2)
 		except:
 			raise exc.JointCreationError()
 			inner_joint.attach(body1.get_inner_object(), body2.get_inner_object())
 			inner_joint.setAnchor(anchor)
 			inner_joint.setAxis(axis) # see contrib.Ragdoll.addHingeJoint for possible modification
-			
+
 			# TODO: necessary?
 			lo_stop = -ode.Infinity
 			hi_stop = ode.Infinity
 			inner_joint.setParam(ode.ParamLoStop, lo_stop)
 			inner_joint.setParam(ode.ParamHiStop, hi_stop)
-			
+
 			super(Rotary, self).__init__(world, inner_joint, body1, body2)
 		except:
 			raise exc.JointCreationError()
-	
+
 	def add_torque(self, torque):
-		'''
-		Applies the torque about the rotation axis
+		"""Applies the torque about the rotation axis
 		torque: float
-		'''
+		"""
 		try:
 			self._inner_joint.addTorque(torque)
 		except:
 			raise exc.PhysicsEngineException('Failed to add torque to this joint')
-	
+
 	def get_angle(self):
-		'''
-		Returns the angle (float) between the two bodies. Its value is between -pi and +pi.
-		The zero angle is determined by the position of the bodies when joint anchor is set
-		'''
+		"""Returns the angle (float) between the two bodies. Its value is
+		between -pi and +pi. The zero angle is determined by the position of
+		the bodies when joint anchor is set."""
 		try:
 			return self._inner_joint.getAngle()
 		except:
 			raise exc.PhysicsEngineException('Failed to get the angle of this joint')
-	
+
 	def get_angle_rate(self):
-		'''
-		Returns the angle rate (float).
-		'''
+		"""Returns the angle rate (float)"""
 		try:
 			return self._inner_joint.getAngleRate()
 		except:
 			raise exc.PhysicsEngineException('Failed to get the angle rate of this joint')
-	
+
 	def set_speed(self, speed, max_force=None):
 		if max_force:
 			self._inner_joint.setParam(ode.ParamFMax, max_force)
 		self._inner_joint.setParam(ode.ParamVel, speed)
-			
+
 class Caster(Joint):
 	pass
 
 			inner_joint.setAnchor(anchor)
 			inner_joint.setAxis1(axis1) # see contrib.Ragdoll.addHingeJoint for possible modification
 			inner_joint.setAxis2(axis2)
-			
+
 			# TODO: necessary?
-			lo_stop1 = -ode.Infinity 
+			lo_stop1 = -ode.Infinity
 			hi_stop1 = ode.Infinity
-			lo_stop2 = -ode.Infinity 
+			lo_stop2 = -ode.Infinity
 			hi_stop2 = ode.Infinity
 			inner_joint.setParam(ode.ParamLoStop, lo_stop1)
 			inner_joint.setParam(ode.ParamHiStop, hi_stop1)
 			inner_joint.setParam(ode.ParamLoStop2, lo_stop2)
 			inner_joint.setParam(ode.ParamHiStop2, hi_stop2)
-			
+
 			super(Universal, self).__init__(world, inner_joint, body1, body2)
 		except:
 			raise exc.JointCreationError()
 			inner_joint = ode.BallJoint(world)
 			inner_joint.attach(body1.get_inner_object(), body2.get_inner_object())
 			inner_joint.setAnchor(anchor)
-			
+
 			super(BallSocket, self).__init__(world, inner_joint, body1, body2)
 		except:
 			raise exc.JointCreationError()
 	pass
 
 class JointCollection:
-	
+
 	# TODO: allow true duplicated? weak-duplicated (same bodies, different joint)? variables for that?
-	
+
 	def __init__(self):
 		self._coll = []
-	
+
 	def exists(self, body1, body2):
 		raise NotImplementedError()
-	
+
 	def count(self):
 		return len(self._coll)
-	
+
 	def add_joint(self, joint, warn=True):
 		if self._coll.count(joint) == 0:
 			self._coll.append(joint)
 		self.force2 = force2
 		self.torque1 = torque1
 		self.torque2 = torque2
-	
+
 	def get_body1(self):
 		return self._body1
-	
+
 	def get_body2(self):
 		return self._body2
 
 class ContactGroup:
-	
+
 	def __init__(self):
 		self._contacts = []
-	
+
 	def add(self, contact):
 		raise NotImplementedError()
-	
+
 	def remove(self, contact):
 		raise NotImplementedError()
-	
+
 	def clear(self):
 		raise NotImplementedError()
-	
+
 	def count(self):
 		raise NotImplementedError()

ars/model/simulator/__init__.py

 import time
 
 import ars.graphics.adapters as gp
-import ars.model.contrib.ragdoll as cb
+#import ars.model.contrib.ragdoll as cb
 import ars.model.geometry.shapes as shapes
 import ars.model.robot.joints as jo
 import ars.utilities.generic as gu
 		self.screenshot_recorder_callback = None
 
 	def add_basic_simulation_objects(self):
-		''' create the basic simulation objects '''
+		"""create the basic simulation objects"""
 		self._contact_group = phs.create_joint_group() # for the contact joints generated during collisions
 		self._world = phs.create_world() # create a world object (physical)
 		self._space = coll.Space()
 
 
 	def update_actors(self):
-		'''
-		Update the position and rotation of each simulated object's corresponding actor.
-		'''
+		"""Update the position and rotation of each simulated object's
+		corresponding actor"""
 		for key_ in self._objects:
 			try:
 				if self._objects[key_].has_body():
 		return self.add_object(SimulatedObject(name, actor=gAxes))
 
 	def add_floor(self, normal=(0,1,0), dist=0, box_size=(5,0.1,5), box_center=(0,0,0), color=(0.2,0.5,0.5)):
-		'''
-		Create a plane geom to simulate a floor. It won't be used later explicitly.
-		Space object has a reference to it
-		'''
+		"""Create a plane geom to simulate a floor. It won't be used explicitly
+		later (space object has a reference to it)"""
 		# FIXME: the relation between ODE's definition of plane and the center of the box
 		self._floor_geom = phs.create_plane_geom(self._space, normal, dist)
 		gFloor = gp.Box(box_size, box_center) #TODO: use normal parameter for orientation
 		return self.add_object(SimulatedObject(name, body, g_capsule))
 
 	def get_actors(self):
-		""" Returns a dictionary with each object actor indexed by its name. """
+		"""Returns a dictionary with each object actor indexed by its name"""
 		actors = {}
 		for key_ in self._objects:
 			actor = self._objects[key_].get_actor()
 		return actors
 
 	def add_object(self, sim_object):
-		""" Adds an object to the internal dictionary of simulated ones. """
+		"""Adds an object to the internal dictionary of simulated ones"""
 		name = sim_object.get_name()
 		if (name in self._objects.keys()) and name:
 			name = name + '/' + str(sim_object.get_body())
 		return self.add_joint(SimulatedJoint(joint=f_joint))
 
 	def add_rotary_joint(self, name, obj1, obj2, anchor, axis):
-		'''
-		Adds a rotary joint between obj1 and obj2, at the specified anchor and with the given axis.
-		If anchor = None, it will be set equal to the position of obj2.
-		'''
+		"""Adds a rotary joint between obj1 and obj2, at the specified anchor
+		and with the given axis. If anchor = None, it will be set equal to the
+		position of obj2"""
 		body1 = obj1.get_body()
 		body2 = obj2.get_body()
 		if not anchor:
 		return self.add_joint(SimulatedJoint(joint=u_joint))
 
 	def add_ball_socket_joint(self, name, obj1, obj2, anchor):
-		'''
-		Adds a "ball and socket" joint between obj1 and obj2, at the specified anchor.
-		If anchor = None, it will be set equal to the position of obj2.
-		'''
+		"""Adds a "ball and socket" joint between obj1 and obj2, at the
+		specified anchor. If anchor = None, it will be set equal to the
+		position of obj2."""
 		body1 = obj1.get_body()
 		body2 = obj2.get_body()
 		if not anchor:
 		self._actor = actor
 
 	def rotate(self, axis, angle):
-		'''
-		Rotate the object by applying a rotation matrix defined by the given axis and angle.
-		'''
+		"""Rotate the object by applying a rotation matrix defined by the given
+		axis and angle"""
 		rot_now = mu.matrix_as_3x3_tuples(self.get_rotation())
 		rot_to_apply = mu.matrix_as_3x3_tuples(mu.calc_rotation_matrix(axis, angle))
 		# the rotation matrix to be applied multiplies from the LEFT the actual one

ars/model/simulator/collision.py

 class Space:
 	def __init__(self):
 		self._inner_object = ode.SimpleSpace() # same as ode.Space(space_type=0)
-		
+
 	def get_inner_object(self):
 		return self._inner_object
-	
+
 	def collide(self, arg, callback):
 		self._inner_object.collide(arg, callback)
 
 def near_callback(args, geom1, geom2):
-	"""
-	Callback function for the collide() method (in ODE). This function checks if the given geoms
-	do collide and creates contact joints (c_joint) if they do, except if they are connected.
-	"""
+	"""Callback function for the collide() method (in ODE). This function
+	checks if the given geoms do collide and creates contact joints (c_joint)
+	if they do, except if they are connected."""
 	c_joint_bounce = 0.2 # default: 0.2
 	c_joint_mu = 500 # default: 500. 0-5 = very slippery, 50-500 = normal, 5000 = very sticky
 

ars/model/simulator/physics.py

 
 class Capsule(Body):
 	def __init__(self, world, space, length, radius, mass=None, density=None):
-		'''
-		create capsule body (aligned along the z-axis so that it matches the Geom created below,
-		which is aligned along the Z-axis by default)
-		'''
+		"""create capsule body (aligned along the z-axis so that it matches the
+		Geom created below,	which is aligned along the Z-axis by default)"""
 
 		if mass is not None:
 			if density is not None:
 class Cylinder(Body):
 
 	def __init__(self, world, space, length, radius, mass=None, density=None):
-		'''
-		create cylinder body (aligned along the z-axis so that it matches the Geom created below,
-		which is aligned along the Z-axis by default)
-		'''
+		"""create cylinder body (aligned along the z-axis so that it matches
+		the Geom created below,	which is aligned along the Z-axis by default)"""
 
 		if mass is not None:
 			if density is not None:
 		raise Exception("Not available in ODE")
 
 def create_world(gravity=(0.0,-9.81,0.0), ERP=0.8, CFM=1E-10):
-	""" Create an ODE world object. """
+	"""Create an ODE world object"""
 	world = ode.World()
 	world.setGravity(gravity)
 	world.setERP(ERP)

ars/utilities/generic.py

 #
 # @author: german
 
-'''
-Generic utility functions to write variables and tuples to file; 
+"""
+Generic utility functions to write variables and tuples to file;
 write and read setting from a file; modify and create tuples.
-'''
+"""
 
 import ConfigParser as cp
 import itertools as it
 	line = ''
 	separator = ','
 	new_line = '\n'
-	
+
 	for item in tuple_:
 		line += str(item)
 		line += separator
 	text_file.write(line)
 
 def write_settings(filename, section, mapped_values):
-	'''
+	"""
 	usage example
 	gu.write_settings('test.cfg', 'mySection', {'a_key':1.1111, 'another_key':False})
-	'''
+	"""
 	config = cp.RawConfigParser()
 	config.add_section(section)
 
 		config.write(configfile)
 
 def read_settings(filename, section):
-	'''
+	"""
 	usage example
 	settings = gu.read_settings('test.cfg', 'mySection')
 	which is a dictionary, e.g. {'a_key':1.1111, 'another_key':False}
-	'''
+	"""
 	config = cp.RawConfigParser()
 	config.read(filename)
-	
+
 	return dict(config.items(section))
 
 def insert_in_tuple(tuple_, index, item_):

ars/utilities/mathematical.py

 # TODO:	attribute the code sections that were taken from somewhere else
 # TODO: create a test for calc_rotation_matrix
 
-'''
+"""
 Functions to perform operations over vectors and matrices;
 deal with homogeneous transforms; convert angles and other structures.
-'''
+"""
 
 import math
 from math import sqrt, pi, cos, sin, acos
 	return tuple(result)
 
 def rot_matrix_to_hom_transform(rot_matrix):
-	'''
-	From transform.r2t in Corke's Robotic Toolbox (python) rot_matrix 3x3 matrix.
-	It may be a tuple, tuple of tuples or the result of numpy.mat()
-	'''
+	"""From transform.r2t in Corke's Robotic Toolbox (python) rot_matrix 3x3
+	matrix.	It may be a tuple, tuple of tuples or the result of numpy.mat()"""
 	import numpy as np
 
 	if isinstance(rot_matrix, tuple):
 						np.mat([0,0,0,1])) )
 
 def matrix3_multiply(matrix1, matrix2):
-	'''
-	returns the matrix multiplication of matrix1 and matrix2.
-	'''
+	"""returns the matrix multiplication of matrix1 and matrix2"""
 	#TODO: check objects are valid, or use exceptions to catch errors raised by numpy
 
 	import numpy as np
 	return matrix_as_3x3_tuples(tuple(result.flatten()))
 
 def matrix_as_tuple(matrix_):
-	'''
-	matrix_: nested tuples, e.g. ((1,0),(1,1),(2,5))
-	'''
+	"""matrix_: nested tuples, e.g. ((1,0),(1,1),(2,5))"""
 	#TODO: improve a lot
 	return gut.nested_iterable_to_tuple(matrix_)
 
 
 class Transform:
 	def __init__(self, position, rot_matrix):
-		'''
+		"""
 		position: a 3-tuple
 		rot_matrix: a 9-tuple
-		'''
+		"""
 		if not rot_matrix:
 			rot_matrix = []
 			rot_matrix[0:3] = (1,0,0)
 #===============================================================================
 
 def sign(x):
-	"""Returns 1.0 if x is positive, -1.0 if x is negative or zero."""
+	"""Returns 1.0 if x is positive, -1.0 if x is negative or zero"""
 	if x > 0.0: return 1.0
 	else: return -1.0
 
 def length2(vector):
-	"""Returns the length of a 2-dimensions vector."""
+	"""Returns the length of a 2-dimensions vector"""
 	return sqrt(vector[0]**2 + vector[1]**2)
 
 def length3(vector):
-	"""Returns the length of a 3-dimensions vector."""
+	"""Returns the length of a 3-dimensions vector"""
 	#TODO: convert it so it can handle vector of any dimension
 	return sqrt(vector[0]**2 + vector[1]**2 + vector[2]**2)
 
 def neg3(vector):
-	"""Returns the negation of 3-vector vector."""
+	"""Returns the negation of 3-vector vector"""
 	#TODO: convert it so it can handle vector of any dimension
 	return (-vector[0], -vector[1], -vector[2])
 
 def add3(vector1, vector2):
-	"""Returns the sum of 3-vectors vector1 and vector2."""
+	"""Returns the sum of 3-vectors vector1 and vector2"""
 	#TODO: convert it so it can handle vector of any dimension
 	return (vector1[0] + vector2[0], vector1[1] + vector2[1], vector1[2] + vector2[2])
 
 def sub3(vector1, vector2):
-	"""Returns the difference between 3-vectors vector1 and vector2."""
+	"""Returns the difference between 3-vectors vector1 and vector2"""
 	#TODO: convert it so it can handle vector of any dimension
 	return (vector1[0] - vector2[0], vector1[1] - vector2[1], vector1[2] - vector2[2])
 
 def mult_by_scalar3(vector, scalar):
-	"""Returns 3-vector vector multiplied by scalar scalar."""
+	"""Returns 3-vector vector multiplied by scalar scalar"""
 	#TODO: convert it so it can handle vector of any dimension
 	return (vector[0] * scalar, vector[1] * scalar, vector[2] * scalar)
 
 def div_by_scalar3(vector, scalar):
-	"""Returns 3-vector vector divided by scalar scalar."""
+	"""Returns 3-vector vector divided by scalar scalar"""
 	#TODO: convert it so it can handle vector of any dimension
 	return (vector[0] / scalar, vector[1] / scalar, vector[2] / scalar)
 
 def dist3(vector1, vector2):
-	"""Returns the distance between point 3-vectors vector1 and vector2."""
+	"""Returns the distance between point 3-vectors vector1 and vector2"""
 	#TODO: convert it so it can handle vector of any dimension
 	return length3(sub3(vector1, vector2))
 
 def norm3(vector):
-	"""Returns the unit length 3-vector parallel to 3-vector vector."""
+	"""Returns the unit length 3-vector parallel to 3-vector vector"""
 	#TODO: convert it so it can handle vector of any dimension
 	l = length3(vector)
 	if (l > 0.0):
 		return (0.0, 0.0, 0.0)
 
 def dot_product3(vector1, vector2):
-	"""Returns the dot product of 3-vectors vector1 and vector2."""
+	"""Returns the dot product of 3-vectors vector1 and vector2"""
 	#TODO: convert it so it can handle vector of any dimension
 	return (vector1[0] * vector2[0] + vector1[1] * vector2[1] + vector1[2] * vector2[2])
 
 def cross_product(vector1, vector2):
-	"""Returns the cross_product product of 3-vectors vector1 and vector2."""
+	"""Returns the cross_product product of 3-vectors vector1 and vector2"""
 	return (vector1[1] * vector2[2] - vector1[2] * vector2[1],
 		vector1[2] * vector2[0] - vector1[0] * vector2[2],
 		vector1[0] * vector2[1] - vector1[1] * vector2[0])
 
 def project3(vector, unit_vector):
-	"""Returns projection of 3-vector vector onto unit 3-vector unit_vector."""
+	"""Returns projection of 3-vector vector onto unit 3-vector unit_vector"""
 	#TODO: convert it so it can handle vector of any dimension
 	return mult_by_scalar3(vector, dot_product3(norm3(vector), unit_vector))
 
 def acos_dot3(vector1, vector2):
-	"""Returns the angle between unit 3-vectors vector1 and vector2."""
+	"""Returns the angle between unit 3-vectors vector1 and vector2"""
 	x = dot_product3(vector1, vector2)
 	if x < -1.0: return pi
 	elif x > 1.0: return 0.0
 	else: return acos(x)
 
 def rotate3(rot_matrix, vector):
-	"""Returns the rotation of 3-vector vector by 3x3 (row major) matrix rot_matrix."""
+	"""Returns the rotation of 3-vector vector by 3x3 (row major) matrix rot_matrix"""
 	return (vector[0] * rot_matrix[0] + vector[1] * rot_matrix[1] + vector[2] * rot_matrix[2],
 		vector[0] * rot_matrix[3] + vector[1] * rot_matrix[4] + vector[2] * rot_matrix[5],
 		vector[0] * rot_matrix[6] + vector[1] * rot_matrix[7] + vector[2] * rot_matrix[8])
 
 def transpose3(matrix):
-	"""Returns the inversion (transpose) of 3x3 rotation matrix matrix."""
+	"""Returns the inversion (transpose) of 3x3 rotation matrix matrix"""
 	#TODO: convert it so it can handle vector of any dimension
 	return (matrix[0], matrix[3], matrix[6],
 		matrix[1], matrix[4], matrix[7],
 		matrix[2], matrix[5], matrix[8])
 
 def z_axis(rot_matrix):
-	"""Returns the z-axis vector from 3x3 (row major) rotation matrix rot_matrix."""
+	"""Returns the z-axis vector from 3x3 (row major) rotation matrix rot_matrix"""
 	#TODO: convert it so it can handle vector of any dimension, and any column
 	return (rot_matrix[2], rot_matrix[5], rot_matrix[8])
 
 		t * axis[2]**2 + cos_theta)
 
 def make_OpenGL_matrix(rotation, position):
-	"""
-	Returns an OpenGL compatible (column-major, 4x4 homogeneous) transformation
-	matrix from ODE compatible (row-major, 3x3) rotation matrix rotation and position
-	vector position.
-	"""
+	"""Returns an OpenGL compatible (column-major, 4x4 homogeneous)
+	transformation matrix from ODE compatible (row-major, 3x3) rotation matrix
+	rotation and position vector position"""
 	return (
 		rotation[0], rotation[3], rotation[6], 0.0,
 		rotation[1], rotation[4], rotation[7], 0.0,
 		position[0], position[1], position[2], 1.0)
 
 def get_body_relative_vector(body, vector):
-	"""
-	Returns the 3-vector vector transformed into the local coordinate system of ODE
-	body body.
-	"""
+	"""Returns the 3-vector vector transformed into the local coordinate system
+	of ODE body 'body'"""
 	return rotate3(transpose3(body.get_rotation()), vector)
 
 #===============================================================================

bin/ControlledSimpleArm.py

 import ars.constants as cts
 
 def output_data(time, sp, cv, error, torque):
-	
-	print('time: %f, sp: %f, cv: %f, error: %f, torque: %f' % 
+
+	print('time: %f, sp: %f, cv: %f, error: %f, torque: %f' %
 		(time, sp, cv, error, torque))
 
 class ControlledSimpleArm(Program):
-	
+
 	R1_TORQUE = 3
-	
+
 	OFFSET = (2.5,1,2.5)
-	
+
 	BOX_PARAMS = (((3,0.5,3),(0,-0.75,0)),{'density':1}) # ((size, center), density)
 	LINK1_PARAMS = ((0.8, 0.1,(0,0,0)),{'density':1}) # ((length, radius, center), density)
 	LINK2_PARAMS = ((0.6,0.1,(0,0.7,0.2)),{'density':1})
-	
+
 	SP_STEP = 0.1
 	q2_INITIAL_SP = 0.0 # mut.pi/3 # set point
 	R2_KP = 1.0 # controller proportional action
 	R2_KD = 0.5 # controller derivative action
-	
+
 	Q1_FRICTION_COEFF = 0.01
 	Q2_FRICTION_COEFF = 0.01
-	
+
 	def __init__(self):
 		Program.__init__(self)
 		self.key_press_functions.add('a', self.rotate_clockwise)
 		self.key_press_functions.add('z', self.rotate_counterlockwise)
 		self.key_press_functions.add('d', self.increase_sp)
 		self.key_press_functions.add('c', self.decrease_sp)
-		
+
 		self.set_pre_step_callback(self.on_pre_step)
-		
+
 		self.sp = self.q2_INITIAL_SP
 		self.previous_error = 0.0
-	
+
 	def create_sim_objects(self):
-		
+
 		box = self.sim.add_box(*self.BOX_PARAMS[0], **self.BOX_PARAMS[1])
 		link1 = self.sim.add_capsule(*self.LINK1_PARAMS[0], **self.LINK1_PARAMS[1])
 		link2 = self.sim.add_capsule(*self.LINK2_PARAMS[0], **self.LINK2_PARAMS[1])
-		
+
 		# bodies are rotated before attaching themselves through joints
 		self.sim.get_object(link1).rotate(cts.X_AXIS, mut.pi/2)
 		self.sim.get_object(link2).rotate(cts.X_AXIS, mut.pi/2)
-		
+
 		self.sim.get_object(box).offset_by_position(self.OFFSET)
 		self.sim.get_object(link1).offset_by_position(self.OFFSET)
 		self.sim.get_object(link2).offset_by_position(self.OFFSET)
-		
+
 		self.sim.add_rotary_joint('r1',					# name, obj1, obj2, anchor, axis
-							self.sim.get_object(box), 
-							self.sim.get_object(link1), 
+							self.sim.get_object(box),
+							self.sim.get_object(link1),
 							None, cts.Y_AXIS)
 		r2_anchor = mut.sub3(self.sim.get_object(link2).get_position(),
 							(0,self.LINK2_PARAMS[0][0]/2,0)) # (0, length/2, 0)
-		self.sim.add_rotary_joint('r2', 
-							self.sim.get_object(link1), 
-							self.sim.get_object(link2), 
+		self.sim.add_rotary_joint('r2',
+							self.sim.get_object(link1),
+							self.sim.get_object(link2),
 							r2_anchor, cts.Z_AXIS)
 
 	def on_pre_step(self):
 			cv = self.get_q2()
 			q1p = self.get_q1p()
 			q2p = self.get_q2p()
-			
+
 			mv = self.get_compensation(self.sp, cv, time_step)
 			self.apply_torque_to_joints(0, mv)
 			self.apply_friction(q1p, q2p)
-			
+
 			output_data(time, self.sp, cv, self.sp - cv, mv)
 			#print('q1p: %f, q2p: %f' % (q1p, q2p))
-			
+
 		except Exception as e:
 			print('Exception when executing on_pre_step: %s' % str(e))
-	
+
 	def rotate_clockwise(self):
 		self.apply_torque_to_joints(self.R1_TORQUE, 0)
-		
+
 	def rotate_counterlockwise(self):
 		self.apply_torque_to_joints(-self.R1_TORQUE, 0)
-	
+
 	def apply_torque_to_joints(self, torque1, torque2):
 		if torque1 is not None:
 			self.sim.get_joint('r1').add_torque(torque1)
 		if torque2 is not None:
 			self.sim.get_joint('r2').add_torque(torque2)
-	
+
 	def increase_sp(self):
 		self.sp += self.SP_STEP
-	
+
 	def decrease_sp(self):
 		self.sp -= self.SP_STEP
-	
+
 	def get_q2(self):
 		return self.sim.get_joint('r2').get_joint().get_angle()
-	
+
 	def get_q1p(self):
 		return self.sim.get_joint('r1').get_joint().get_angle_rate()
-	
+
 	def get_q2p(self):
 		return self.sim.get_joint('r2').get_joint().get_angle_rate()
-	
+
 	def get_compensation(self, sp, q, time_step):
-		''' PD controller '''
+		"""PD controller"""
 		error = (sp - q)
 		error_p = (error - self.previous_error) / time_step
 		torque = self.R2_KP * error + self.R2_KD * error_p
 		self.previous_error = error
 		return torque
-	
+
 	def apply_friction(self, q1p, q2p):
 		self.apply_torque_to_joints(-q1p * self.Q1_FRICTION_COEFF, -q2p * self.Q2_FRICTION_COEFF)
 

bin/IROS/example3_speed_profile.py

 from VehicleWithArm import VehicleWithArm, mut
 
 class Example3(VehicleWithArm):
-	
+
 	#WINDOW_SIZE = (1024,630)
 	CAMERA_POSITION = (0,8,25) # (0,8,15)
-	
+
 	FPS = 50
 	STEPS_PER_FRAME = 80
 
 
 	LINK1_PARAMS = ((0.8, 0.1,(0,0,0)),{'mass':1}) # ((length, radius, center), mass)
 	LINK2_PARAMS = ((0.6,0.1,(0,0.7,0.2)),{'mass':1})
-	
+
 	Q1_FRICTION_COEFF = 0.02
 	Q2_FRICTION_COEFF = 0.02
-	
+
 	KP = 10 # controller proportional action
-	
+
 	# speed profile setup
 	speeds = ((0,0), (1,0), (5,1), (9,1), (13,0), (14,0)) # (time,speed)
 	speed_i = 0
-	
+
 	def __init__(self):
-		""" Constructor, calls first the superclass constructor. """
+		"""Constructor, calls the superclass constructor first"""
 		VehicleWithArm.__init__(self)
 		self.sim.get_object(self.chassis).get_actor().set_color((0.8,0,0))
-		
+
 		self.r1_angle_rate_prev = 0.0
 		self.r2_angle_rate_prev = 0.0
 
 	def on_pre_step(self):
 		try:
 			time = self.sim.sim_time
-			
+
 			if self.speed_i < len(self.speeds) - 1:
 				if time > self.speeds[self.speed_i + 1][0]:
 					self.speed_i += 1
 			elif self.speed_i == len(self.speeds) - 1:
 				pass
-			
+
 			pos = self.sim.get_object(self.chassis).get_position()
 			q1 = self.sim.get_joint('r1').get_joint().get_angle()
 			q1p = self.sim.get_joint('r1').get_joint().get_angle_rate()
 			q2 = self.sim.get_joint('r2').get_joint().get_angle()
 			q2p = self.sim.get_joint('r2').get_joint().get_angle_rate()
-						
+
 			linear_vel = self.sim.get_object(self.chassis).get_linear_velocity()
 			linear_vel_XZ = (linear_vel[0], linear_vel[2])
 			cv = mut.length2(linear_vel_XZ) * mut.sign(linear_vel[0])
 			torque = self.compensate(sp, cv)
 			self.apply_torque_to_wheels(torque, torque)
 			self.apply_friction(q1p, q2p)
-			
-			print('%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e' % 
+
+			print('%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e' %
 				(time,pos[0],cv,sp,q1,q1p,q2,q2p,torque))
-			
+
 		except Exception as e:
 			print('Exception when executing on_pre_step: %s' % str(e))
-	
+
 	def calc_desired_speed(self, time):
-		
+
 		if self.speed_i == len(self.speeds) - 1:
 			return float(self.speeds[self.speed_i][1])
-		
+
 		elif 0 <= self.speed_i < len(self.speeds) - 1:
 			time_diff = time - self.speeds[self.speed_i][0]
 			time_period = self.speeds[self.speed_i + 1][0] - self.speeds[self.speed_i][0]
 			return (next_speed - prev_speed) * (time_diff / time_period) + prev_speed
 		else:
 			raise Exception('invalid speed_i value: %d' % self.speed_i)
-	
+
 	def compensate(self, sp, cv):
 		return (sp - cv) * self.KP
 
 if __name__ == '__main__':
 	sim_program = Example3()
 	sim_program.start()
-	
+
 	# print mass of bodies defined with a density value
 	ball_body = sim_program.sim.get_object(sim_program.ball).get_body()
 	chassis_body = sim_program.sim.get_object(sim_program.chassis).get_body()

bin/IROS/example4_sinusoidal_terrain.py

 from VehicleWithArm import VehicleWithArm
 
 def random_heightfield(num_x, num_z, scale=1.0):
-	"""
-	A height field where values are completely random.
-	"""
+	"""A height field where values are completely random"""
 	# that x and z are integers, not floats, does not matter
 	verts=[]
 	for x in range(num_x):
 	return verts
 
 def sinusoidal_heightfield(num_x, num_z, height_scale=1.0, frequency_x=1.0):
-	"""
-	Creates the vertices corresponding to a sinusoidal heightfield along the X axis.
-	The height_scale controls the amplitude of the wave, and frequency_x its frequency.
-	"""
+	"""Creates the vertices corresponding to a sinusoidal heightfield along the
+	X axis. The height_scale controls the amplitude of the wave, and
+	frequency_x its frequency"""
 	# TODO: fix the frequency units
 	verts=[]
 	for x in range(num_x):
 	return verts
 
 def constant_heightfield(num_x, num_z, height=0.0):
-	"""
-	A height field where all the values are the same.
-	"""
+	"""A height field where all the values are the same"""
 	# that x and z are integers, not floats, does not matter
 	verts=[]
 	for x in range(num_x):
 	R2_KD = 15.0
 
 	def __init__(self):
-		""" Constructor, calls first the superclass constructor. """
+		"""Constructor, calls the superclass constructor first"""
 		VehicleWithArm.__init__(self)
 		self.set_pre_step_callback(self.on_pre_step)
 
 			print('Exception when executing on_pre_step: %s' % str(e))
 
 	def get_arm_compensation(self, q1, q2):
-		""" Calculate the control torque with a PD controller """
+		"""Calculate the control torque with a PD controller"""
 		time_step = self.sim.get_time_step()
 		error_q1 = (self.q1_SP - q1)
 		error_q2 = (self.q2_SP - q2)

bin/IROS/example4b_sinusoidal_terrain_with_screenshot_recorder.py

 from example4_sinusoidal_terrain import Example4
 
 class Example4SR(Example4):
-	
+
 	# screenshot recorder
 	RECORDER_BASE_FILENAME = 'sin'
 	RECORD_PERIODICALLY = True
-	
+
 	def __init__(self):
-		""" Constructor, calls first the superclass constructor. """
+		"""Constructor, calls the superclass constructor first"""
 		Example4.__init__(self)
 		self.create_screenshot_recorder(
 			self.RECORDER_BASE_FILENAME, self.RECORD_PERIODICALLY)

bin/IROS/example5_vehicle_with_user_input.py

 from VehicleWithArm import VehicleWithArm, mut
 
 class Example5(VehicleWithArm):
-	
+
 	FPS = 50
 	STEPS_PER_FRAME = 80
 	CAMERA_POSITION = (15,10,15)
 	PRINT_KEY_INFO = False
-	
+
 	WHEEL_TORQUE = 3
-		
+
 	WHEEL_R_PARAMS = ((0.4,0.3,(0,0,-0.5)),{'mass':1}) # ((length, radius, center), mass)
 	WHEEL_L_PARAMS = ((0.4,0.3,(0,0,0.5)),{'mass':1})
-	
+
 	# joint 2 controller params
 	SP_STEP = 0.1 # set point step
 	q2_INITIAL_SP = 0.0 # initial set point
 	R2_KP = 3.0 # controller proportional action
 	R2_KD = 3.0 # controller derivative action
-	
+
 	def __init__(self, use_capsule_wheels=False, frictionless_arm=True):
-		""" Constructor, which calls the superclass constructor. """
+		"""Constructor, calls the superclass constructor first"""
 		VehicleWithArm.__init__(self, use_capsule_wheels, frictionless_arm)
-		
+
 		self.key_press_functions.add('d', self.increase_sp)
 		self.key_press_functions.add('c', self.decrease_sp)
-		
+
 		self.sp = self.q2_INITIAL_SP
 		self.previous_error = 0.0
 		self.torque_w1 = 0.0
 			pos = self.sim.get_object(self.chassis).get_position()
 			q1 = self.sim.get_joint('r1').get_joint().get_angle()
 			q2 = self.sim.get_joint('r2').get_joint().get_angle()
-			
+
 			mv = self.get_compensation(self.sp, q2, time_step)
 			self.apply_torque_to_joints(0, mv) # torque1, torque2
-			
-			print('%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e' % 
+
+			print('%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e\t%.7e' %
 				(time,pos[0],pos[2],q1,q2,self.sp,mv,self.torque_w1,self.torque_w2))
-			
+
 			self.torque_w1 = 0.0
 			self.torque_w2 = 0.0
-			
+
 		except Exception as e:
 			print('Exception when executing on_pre_step: %s' % str(e))
-	
+
 	def apply_torque_to_wheels(self, torque1, torque2):
 		VehicleWithArm.apply_torque_to_wheels(self, torque1, torque2)
 		self.torque_w1 = torque1
 		self.torque_w2 = torque2
-	
+
 	def increase_sp(self):
-		""" Increase angle set point. """
+		"""Increase angle set point"""
 		self.sp += self.SP_STEP
-	
+
 	def decrease_sp(self):
-		""" Decrease angle set point. """
+		"""Decrease angle set point"""
 		self.sp -= self.SP_STEP
-	
+
 	def get_compensation(self, sp, q, time_step):
-		""" Calculate the control torque with a PD controller """
+		"""Calculate the control torque with a PD controller"""
 		error = (sp - q)
 		error_p = (error - self.previous_error) / time_step
 		torque = self.R2_KP * error + self.R2_KD * error_p
 #
 # @author: german
 
-"""
-Runs a simulation of a simple arm, with 2 links and 2 rotary joints
-"""
+"""Runs a simulation of a simple arm, with 2 links and 2 rotary joints"""
 
 from ars.app import Program
 import ars.utilities.mathematical as mut
 import ars.constants as cts
 
 class SimpleArm(Program):
-	
+
 	TORQUE = 3
-	
+
 	OFFSET = (2.5,1,2.5)
-	
+
 	BOX_PARAMS = (((3,0.5,3),(0,-0.75,0)),{'density':1}) # ((size, center), density)
 	LINK1_PARAMS = ((0.8, 0.1,(0,0,0)),{'density':1}) # ((length, radius, center), density)
 	LINK2_PARAMS = ((0.6,0.1,(0,0.7,0.2)),{'density':1})
-	
+
 	def __init__(self):
 		Program.__init__(self)
 		self.key_press_functions.add('a', self.rotate_clockwise)
 		self.key_press_functions.add('z', self.rotate_counterlockwise)
-	
+
 	def create_sim_objects(self):
-		
+
 		box = self.sim.add_box(*self.BOX_PARAMS[0], **self.BOX_PARAMS[1])
 		link1 = self.sim.add_capsule(*self.LINK1_PARAMS[0], **self.LINK1_PARAMS[1])
 		link2 = self.sim.add_capsule(*self.LINK2_PARAMS[0], **self.LINK2_PARAMS[1])
-		
+
 		# bodies are rotated before attaching themselves through joints
 		self.sim.get_object(link1).rotate(cts.X_AXIS, mut.pi/2)
 		self.sim.get_object(link2).rotate(cts.X_AXIS, mut.pi/2)
-		
+
 		self.sim.get_object(box).offset_by_position(self.OFFSET)
 		self.sim.get_object(link1).offset_by_position(self.OFFSET)
 		self.sim.get_object(link2).offset_by_position(self.OFFSET)
-		
+
 		self.sim.add_rotary_joint('r1',                    # name, obj1, obj2, anchor, axis
-							self.sim.get_object(box), 
-							self.sim.get_object(link1), 
+							self.sim.get_object(box),
+							self.sim.get_object(link1),
 							None, cts.Y_AXIS)
 		r2_anchor = mut.sub3(self.sim.get_object(link2).get_position(),
 							(0,self.LINK2_PARAMS[0][0]/2,0)) # (0, length/2, 0)
-		self.sim.add_rotary_joint('r2', 
-							self.sim.get_object(link1), 
-							self.sim.get_object(link2), 
+		self.sim.add_rotary_joint('r2',
+							self.sim.get_object(link1),
+							self.sim.get_object(link2),
 							r2_anchor, cts.Z_AXIS)
-	
+
 	def rotate_clockwise(self):
 		self.sim.get_joint('r1').add_torque(self.TORQUE)
-		
+
 	def rotate_counterlockwise(self):
 		self.sim.get_joint('r1').add_torque(-self.TORQUE)
 
 import ars.constants as cts
 
 class Vehicle2(Program):
-	
+
 	TORQUE = 30
-	
+
 	OFFSET = (3,1,3)
-	
+
 	FLOOR_BOX_SIZE = (20,0.01,20)
-	
+
 	def __init__(self):
-		""" Constructor, calls first the superclass constructor. """
+		"""Constructor, calls the superclass constructor first"""
 		Program.__init__(self)
 		self.key_press_functions.add('up', self.go_forwards, True)
 		self.key_press_functions.add('down', self.go_backwards, True)
 		self.key_press_functions.add('left', self.turn_left, True)
 		self.key_press_functions.add('right', self.turn_right, True)
-	
+
 	def create_sim_objects(self):
-		'''
-		Implementation of the required method.
-		Creates and sets up all the objects of the simulation.
-		'''
-		
+		"""Implementation of the required method. Creates and sets up all the
+		objects of the simulation."""
+
 		offset = self.OFFSET
-		
+
 		wheelR = self.sim.add_cylinder(0.4, 0.3, (0,0,-0.5), density=1) # length, radius, center, density
 		wheelL = self.sim.add_cylinder(0.4, 0.3, (0,0,0.5), density=1)
 		ball = self.sim.add_sphere(0.3, (1,0,0), density=1) # radius, center, density
 		chassis = self.sim.add_box((2,0.2,1.5), (0.5,0.45,0), density=10) # size, center, density
-		
+
 		self.sim.add_rotary_joint('r1',				   # name, obj1, obj2, anchor, axis
-							self.sim.get_object(chassis), 
-							self.sim.get_object(wheelR), 
+							self.sim.get_object(chassis),
+							self.sim.get_object(wheelR),
 							None, cts.Z_AXIS)
-		self.sim.add_rotary_joint('r2', 
-							self.sim.get_object(chassis), 
-							self.sim.get_object(wheelL), 
+		self.sim.add_rotary_joint('r2',
+							self.sim.get_object(chassis),
+							self.sim.get_object(wheelL),
 							None, cts.Z_AXIS)
 		self.sim.add_ball_socket_joint('bs',			  # name, obj1, obj2, anchor
-								self.sim.get_object(chassis), 
+								self.sim.get_object(chassis),
 								self.sim.get_object(ball),
 								None)
-		
+
 		self.sim.get_object(wheelR).offset_by_position(offset)
 		self.sim.get_object(wheelL).offset_by_position(offset)
 		self.sim.get_object(ball).offset_by_position(offset)
 		self.sim.get_object(chassis).offset_by_position(offset)
-		
+
 		# test
 		#print(self.sim.get_object(wheelR).get_actor().set_color((0.8,0,0)))
-	
-	
+
+
 	def go_forwards(self):
-		""" Rotate both powered wheels in the same direction, forwards """
+		"""Rotate both powered wheels in the same direction, forwards"""
 		self.sim.get_joint('r1').add_torque(self.TORQUE)
 		self.sim.get_joint('r2').add_torque(self.TORQUE)
-	
+
 	def go_backwards(self):
-		""" Rotate both powered wheels in the same direction, backwards """
+		"""Rotate both powered wheels in the same direction, backwards"""
 		self.sim.get_joint('r1').add_torque(-self.TORQUE)
 		self.sim.get_joint('r2').add_torque(-self.TORQUE)
-		
+
 	def turn_left(self):
-		"""
-		Rotate both powered wheels in different directions,
-		with a global counter-clockwise rotation (from above).
-		"""
+		"""Rotate both powered wheels in different directions, with a global
+		counter-clockwise rotation (from above)"""
 		self.sim.get_joint('r1').add_torque(-self.TORQUE)
 		self.sim.get_joint('r2').add_torque(self.TORQUE)
-		
+
 	def turn_right(self):
-		"""
-		Rotate both powered wheels in different directions,
-		with a global clockwise rotation (from above).
-		"""
+		"""Rotate both powered wheels in different directions, with a global
+		clockwise rotation (from above)"""
 		self.sim.get_joint('r1').add_torque(self.TORQUE)
 		self.sim.get_joint('r2').add_torque(-self.TORQUE)
 

bin/Vehicle2WithScreenshots.py

 #
 # @author: german
 
-"""
-Runs a simulation of a vehicle with two powered wheels and one
-free-rotating spherical wheel.
-"""
+"""Runs a simulation of a vehicle with two powered wheels and one
+free-rotating spherical wheel"""
 
 from Vehicle2 import Vehicle2
 
 	FPS = 100 # this is the recording frequency
 	RECORDER_BASE_FILENAME = 'test'
 	RECORD_PERIODICALLY = True
-	
+
 	def __init__(self):
 		Vehicle2.__init__(self)
 		self.create_screenshot_recorder(

bin/VehicleWithArm.py

 Runs a simulation of a vehicle with two powered wheels and one
 free-rotating spherical wheel. It has a 2-link robotic arm attached,
 with joints either friction-free or with friction proportional to
-joint speed. 
+joint speed.
 """
 
 from ars.app import Program
 import ars.constants as cts
 
 class VehicleWithArm(Program):
-	
+
 	STEPS_PER_FRAME = 200
 	BACKGROUND_COLOR = (0.8,0.8,0.8)
 	FLOOR_BOX_SIZE = (20,0.01,20)
-	
+
 	WHEEL_TORQUE = 3
 	VEHICLE_OFFSET = (2,0.35,4)
-	
+
 	BALL_PARAMS = ((0.3,(1,0,0)),{'density':1}) # ((radius, center), density)
 	CHASSIS_PARAMS = (((2,0.2,1.5),(0.5,0.45,0)),{'mass':6}) # ((size, center), mass)
-		
+
 	WHEEL_R_PARAMS = ((0.4,0.3,(0,0,-0.5)),{'density':1}) # ((length, radius, center), density)
 	WHEEL_L_PARAMS = ((0.4,0.3,(0,0,0.5)),{'density':1})
-	
+
 	LINK1_PARAMS = ((0.8, 0.1,(0,0,0)),{'density':1}) # ((length, radius, center), density)
 	LINK2_PARAMS = ((0.6,0.1,(0,0.7,0.2)),{'density':1})
-	
+
 	R1_TORQUE = 3
-	
+
 	Q1_FRICTION_COEFF = 0.01
 	Q2_FRICTION_COEFF = 0.01
-	
+
 	def __init__(self, use_capsule_wheels=False, frictionless_arm=True):
-		""" Constructor, which calls the superclass constructor. """
+		"""Constructor, calls the superclass constructor first"""
 		self._use_capsule_wheels = use_capsule_wheels
 		self._frictionless_arm = frictionless_arm
-		
+
 		Program.__init__(self)
 		self.key_press_functions.add('up', self.go_forwards, repeat=True)
 		self.key_press_functions.add('down', self.go_backwards, repeat=True)
 		self.key_press_functions.add('left', self.turn_left, repeat=True)
 		self.key_press_functions.add('right', self.turn_right, repeat=True)
-		
+
 		self.key_press_functions.add('a', self.rotate_clockwise)
 		self.key_press_functions.add('z', self.rotate_counterlockwise)
-		
+
 		self.set_pre_step_callback(self.on_pre_step)
-	
+
 	def create_sim_objects(self):
-		'''
-		Implementation of the required method.
-		Creates and sets up all the objects of the simulation.
-		'''
-		
+		"""Implementation of the required method. Creates and sets up all the
+		objects of the simulation."""
+
 		arm_offset = (0,0.5,0)
-		
+
 		#=======================================================================
 		# VEHICLE
 		#=======================================================================
-		
+
 		if self._use_capsule_wheels:
 			wheelR = self.sim.add_capsule(*self.WHEEL_R_PARAMS[0], **self.WHEEL_R_PARAMS[1])
 			wheelL = self.sim.add_capsule(*self.WHEEL_L_PARAMS[0], **self.WHEEL_L_PARAMS[1])
 		else:
 			wheelR = self.sim.add_cylinder(*self.WHEEL_R_PARAMS[0], **self.WHEEL_R_PARAMS[1])
 			wheelL = self.sim.add_cylinder(*self.WHEEL_L_PARAMS[0], **self.WHEEL_L_PARAMS[1])
-		
+
 		ball = self.sim.add_sphere(*self.BALL_PARAMS[0], **self.BALL_PARAMS[1])
 		chassis = self.sim.add_box(*self.CHASSIS_PARAMS[0], **self.CHASSIS_PARAMS[1])
-		
+
 		self.sim.add_rotary_joint('w1',                   # name, obj1, obj2, anchor, axis
-							self.sim.get_object(chassis), 
-							self.sim.get_object(wheelR), 
+							self.sim.get_object(chassis),
+							self.sim.get_object(wheelR),
 							None, cts.Z_AXIS)
-		self.sim.add_rotary_joint('w2', 
-							self.sim.get_object(chassis), 
-							self.sim.get_object(wheelL), 
+		self.sim.add_rotary_joint('w2',
+							self.sim.get_object(chassis),
+							self.sim.get_object(wheelL),
 							None, cts.Z_AXIS)
 		self.sim.add_ball_socket_joint('bs',              # name, obj1, obj2, anchor
-								self.sim.get_object(chassis), 
+								self.sim.get_object(chassis),
 								self.sim.get_object(ball),
 								None)
-		
+
 		self.sim.get_object(wheelR).offset_by_position(self.VEHICLE_OFFSET)
 		self.sim.get_object(wheelL).offset_by_position(self.VEHICLE_OFFSET)
 		self.sim.get_object(ball).offset_by_position(self.VEHICLE_OFFSET)
 		self.sim.get_object(chassis).offset_by_position(self.VEHICLE_OFFSET)
-		
+
 		#=======================================================================
 		# ROBOTIC ARM
 		#=======================================================================
 		link1 = self.sim.add_capsule(*self.LINK1_PARAMS[0], **self.LINK1_PARAMS[1])
 		link2 = self.sim.add_capsule(*self.LINK2_PARAMS[0], **self.LINK2_PARAMS[1])
-		
+
 		# bodies are rotated before attaching themselves through joints
 		self.sim.get_object(link1).rotate(cts.X_AXIS, mut.pi/2)
 		self.sim.get_object(link2).rotate(cts.X_AXIS, mut.pi/2)
-		
+
 		self.sim.get_object(link1).offset_by_object(self.sim.get_object(chassis))
 		self.sim.get_object(link1).offset_by_position(arm_offset)
 		self.sim.get_object(link2).offset_by_object(self.sim.get_object(link1))
-		
+
 		self.sim.add_rotary_joint('r1',				   # name, obj1, obj2, anchor, axis
-							self.sim.get_object(chassis), 
-							self.sim.get_object(link1), 
+							self.sim.get_object(chassis),
+							self.sim.get_object(link1),
 							None, cts.Y_AXIS)
 		r2_anchor = mut.sub3(self.sim.get_object(link2).get_position(),
 							(0,self.LINK2_PARAMS[0][0]/2,0)) # (0,length/2,0)
-		self.sim.add_rotary_joint('r2', 
-							self.sim.get_object(link1), 
-							self.sim.get_object(link2), 
+		self.sim.add_rotary_joint('r2',
+							self.sim.get_object(link1),
+							self.sim.get_object(link2),
 							r2_anchor, cts.Z_AXIS)
-		
+
 		self.sim.get_object(chassis).get_actor().set_color(cts.COLOR_RED)
 		self.sim.get_object(link1).get_actor().set_color(cts.COLOR_YELLOW)
 		self.sim.get_object(link2).get_actor().set_color(cts.COLOR_NAVY)
-		
+
 		self.chassis = chassis
 		self.wheelR = wheelR
 		self.wheelL = wheelL
 		self.ball = ball
-		
+
 		self.link1 = link1
 		self.link2 = link2
-		
+
 	def go_forwards(self):
-		""" Rotate both powered wheels in the same direction, forwards """
+		"""Rotate both powered wheels in the same direction, forwards"""
 		self.apply_torque_to_wheels(self.WHEEL_TORQUE, self.WHEEL_TORQUE)
-	
+
 	def go_backwards(self):
-		""" Rotate both powered wheels in the same direction, backwards """
+		"""Rotate both powered wheels in the same direction, backwards"""
 		self.apply_torque_to_wheels(-self.WHEEL_TORQUE, -self.WHEEL_TORQUE)
-		
+
 	def turn_left(self):
-		"""
-		Rotate both powered wheels in different directions,
-		with a global counter-clockwise rotation (from above).
-		"""
+		"""Rotate both powered wheels in different directions, with a global
+		counter-clockwise rotation (from above)"""
 		self.apply_torque_to_wheels(-self.WHEEL_TORQUE, self.WHEEL_TORQUE)
-		
+
 	def turn_right(self):
-		"""
-		Rotate both powered wheels in different directions,
-		with a global clockwise rotation (from above).
-		"""
+		"""Rotate both powered wheels in different directions, with a global
+		clockwise rotation (from above)"""
 		self.apply_torque_to_wheels(self.WHEEL_TORQUE, -self.WHEEL_TORQUE)
 
 	def on_pre_step(self):
 			#time = self.sim.sim_time
 			q1p = self.get_q1p()
 			q2p = self.get_q2p()
-			
+
 			if not self._frictionless_arm:
 				self.apply_friction(q1p, q2p)
-			
+
 			print('q1p: %f, q2p: %f' % (q1p, q2p))
-			
+
 		except Exception as e:
 			print('Exception when executing on_pre_step: %s' % str(e))
-	
+
 	def apply_torque_to_wheels(self, torque1, torque2):
 		if torque1 is not None:
 			self.sim.get_joint('w1').add_torque(torque1)
 		if torque2 is not None:
 			self.sim.get_joint('w2').add_torque(torque2)
-	
+
 	def rotate_clockwise(self):
 		self.apply_torque_to_joints(self.R1_TORQUE, 0)
-		
+
 	def rotate_counterlockwise(self):
 		self.apply_torque_to_joints(-self.R1_TORQUE, 0)
-	
+
 	def apply_torque_to_joints(self, torque1, torque2):
 		if torque1 is not None:
 			self.sim.get_joint('r1').add_torque(torque1)
 		if torque2 is not None:
 			self.sim.get_joint('r2').add_torque(torque2)
-	
+
 	def get_q1p(self):
 		return self.sim.get_joint('r1').get_joint().get_angle_rate()
-	
+
 	def get_q2p(self):
 		return self.sim.get_joint('r2').get_joint().get_angle_rate()
-	
+
 	def apply_friction(self, q1p, q2p):
 		self.apply_torque_to_joints(-q1p * self.Q1_FRICTION_COEFF, -q2p * self.Q2_FRICTION_COEFF)
 

bin/VehicleWithControlledArm.py

 from VehicleWithArm import VehicleWithArm
 
 def output_data(time, sp, cv, error, torque):
-	
-	print('time: %f, sp: %f, cv: %f, error: %f, torque: %f' % 
+
+	print('time: %f, sp: %f, cv: %f, error: %f, torque: %f' %
 		(time, sp, cv, error, torque))
 
 class VehicleWithControlledArm(VehicleWithArm):
-		
+
 	WHEEL_R_PARAMS = ((0.4,0.3,(0,0,-0.5)),{'density':1}) # ((length, radius, center), density)
 	WHEEL_L_PARAMS = ((0.4,0.3,(0,0,0.5)),{'density':1})
-	
+
 	SP_STEP = 0.1
 	q2_SP = 0.0 # mut.pi/3 # set point
 	R2_KP = 1.0 # controller proportional action
 	R2_KD = 0.5 # controller derivative action
-	
+
 	def __init__(self, use_capsule_wheels=False, frictionless_arm=True):
-		""" Constructor, which calls the superclass constructor. """
+		"""Constructor, calls the superclass constructor first"""
 		VehicleWithArm.__init__(self, use_capsule_wheels, frictionless_arm)
-		
+
 		self.key_press_functions.add('d', self.increase_sp)
 		self.key_press_functions.add('c', self.decrease_sp)
-		
+
 		self.sp = self.q2_SP
 		self.previous_error = 0.0
 
 			time = self.sim.sim_time
 			time_step = self.sim.get_time_step()
 			cv = self.get_q2()
-			
+
 			mv = self.get_compensation(self.sp, cv, time_step)
 			self.apply_torque_to_joints(0, mv) # torque1, torque2
-			
+
 			output_data(time, self.sp, cv, self.sp - cv, mv)
-			
+
 		except Exception as e:
 			print('Exception when executing on_pre_step: %s' % str(e))
-	
+
 	def increase_sp(self):
-		""" Increase angle set point. """
+		"""Increase angle set point"""
 		self.sp += self.SP_STEP
-	
+
 	def decrease_sp(self):
-		""" Decrease angle set point. """
+		"""Decrease angle set point"""
 		self.sp -= self.SP_STEP
-	
+
 	def get_q2(self):
-		""" Get the current angle of the second rotary joint. """
+		"""Get the current angle of the second rotary joint"""
 		return self.sim.get_joint('r2').get_joint().get_angle()
-	
+
 	def get_compensation(self, sp, q, time_step):
-		""" Calculate the control torque with a PD controller """
+		"""Calculate the control torque with a PD controller"""
 		error = (sp - q)
 		error_p = (error - self.previous_error) / time_step
 		torque = self.R2_KP * error + self.R2_KD * error_p

tests/external-libs/TrimeshCollision.py

 contactGroup = ode.JointGroup()
 
 def nearCallback(args, geom1, geom2):
-	"""
-	Callback function for the collide() method.
-
-	This function checks if the given geoms do collide and creates contact
-	joints if they do.
-	"""
+	"""Callback function for the collide() method. This function checks if the
+	given geoms do collide and creates contact joints if they do."""
 	contactJointBounce = 0.2
 	contactJointMu = 500 # 0-5 = very slippery, 50-500 = normal, 5000 = very sticky
 
 	# check if the objects collide
 	contacts = ode.collide(geom1, geom2)
 	for c in contacts:
-		
+
 		(pos, normal, depth, geom1, geom2) = c.getContactGeomParams()
 		print((pos, normal, depth))
-		
+
 		c.setBounce(contactJointBounce)
 		c.setMu(contactJointMu)
 		j = ode.ContactJoint(world, contactgroup, c)
 	return world
 
 def constant_heightfield(num_x, num_z, height=0.0):
-	"""
-	A height field where all the values are the same.
-	"""
+	"""A height field where all the values are the same"""
 	# that x and z are integers, not floats, does not matter
 	verts=[]
 	for x in range(num_x):
 	return verts
 
 def random_heightfield(num_x, num_z, scale=1.0):
-	"""
-	Based on:
-	Edward Dale - Snowballs: An experiment in Winter frivolity (2006).
-	http://scompt.com/files/cg2/final.pdf
-		
-	A height field where values are completely random.
-	"""
+	"""Based on 'Edward Dale - Snowballs: An experiment in Winter frivolity
+	(2006).' http://scompt.com/files/cg2/final.pdf
+	A height field where values are completely random."""
 	# that x and z are integers, not floats, does not matter
 	verts=[]
 	for x in range(num_x):
 	return verts
 
 def sinusoidal_heightfield(num_x, num_z, height_scale=1.0, frequency_x=1.0):
-	"""
-	Creates the vertices corresponding to a sinusoidal heightfield along the X axis.
-	The height_scale controls the amplitude of the wave, and frequency_x its frequency.
-	@author: German Larrain
-	"""
+	"""Creates the vertices corresponding to a sinusoidal heightfield along the
+	X axis. The height_scale controls the amplitude of the wave, and
+	frequency_x its frequency."""
 	# TODO: fix the frequency units
 	verts=[]
 	for x in range(num_x):
 	return verts
 
 def get_faces(num_x, num_z):
-	"""
-	Based on:
-	Edward Dale - Snowballs: An experiment in Winter frivolity (2006).
-	http://scompt.com/files/cg2/final.pdf
-	
-	A height field is rectilinear, but the faces are only going to be triangular. This
-	method chooses 3 vertices out of each 4 to make a face and the other set to make
-	another triangular face. This is done randomly to eliminate artifacts.
-	"""
+	"""Based on 'Edward Dale - Snowballs: An experiment in Winter frivolity
+	(2006).' http://scompt.com/files/cg2/final.pdf
+	A height field is rectilinear, but the faces are only going to be
+	triangular. This method chooses 3 vertices out of each 4 to make a face and
+	the other set to make another triangular face. This is done randomly to
+	eliminate artifacts."""
 	faces=[]
 	for z in range(num_z-1):
 		for x in range(num_x-1):
 	performSimStepsPerFrame()
 	pos = ball_body.getPosition()
 	ball_actor.SetPosition(*pos)
-	
+
 	iren = obj
 	iren.GetRenderWindow().Render()
 
 	for i in range(stepsPerFrame): #@UnusedVariable
 		# Detect collisions and create contact joints
 		space.collide((world, contactGroup), nearCallback)
-		
+
 		# Simulation step
 		timeStep = dt / stepsPerFrame
 		world.step(timeStep)
 		simTime += timeStep
 		numIter += 1
-		
+
 		# Remove all contact joints
 		contactGroup.empty()
 
 def swap_faces_indices(faces):
-	"""
-	Faces had to change their indices to work with ODE. With the initial get_faces,
-	the normal to the triangle defined by the 3 vertices pointed (following the 
-	right-hand rule) downwards. Swapping the third with the first index, now the
-	triangle normal pointed upwards.
-	"""
-	
+	"""Faces had to change their indices to work with ODE. With the initial
+	'get_faces', the normal to the triangle defined by the 3 vertices pointed
+	(following the right-hand rule) downwards. Swapping the third with the
+	first index, now the triangle normal pointed upwards."""
+
 	new_faces = []
 	for face in faces:
 		new_faces.append((face[2], face[1], face[0]))
 	return new_faces
 
 if __name__ == '__main__':
-	
+
 	world = createOdeWorld()
 	space = ode.Space()
-	
+
 	#===========================================================================
 	# Ball (ODE)
 	#===========================================================================
-