Commits

German Larrain committed c4333d5 Merge

Merge with dev

  • Participants
  • Parent commits 0a547b1, 224c189
  • Branches dev-gui

Comments (0)

Files changed (5)

File ars/app/__init__.py

+"""Main package of the software.
+It contains the Program class which is the core application controller.
 
-# Created on 2011.10.14
-#
-# @author: german
-
-"""
-Main package of the software.
-It contains the Program class which is the core application controller.
 """
 
 from abc import abstractmethod
 
 
 class Program():
+	"""Main class of ARS.
+
+	To run a custom simulation, create a subclass.
+	It must contain an implementation of the 'create_sim_objects' method
+	which will be called during the simulation creation.
+
+	To use it, only two statements are necessary:
+	-create an object of this class (i.e. sim_program = ProgramSubclass() )
+	-call its 'start' method (i.e. sim_program.start() )
 
 	"""
-	Main class of ARS.
-	To run a custom simulation a subclass has to be created.
-	This must contain an implementation of the 'create_sim_objects' method
-	which will be called during the simulation creation.
-	To run this, only two statements are necessary:
-	-create an object of this class (i.e. sim_program = ProgramSubclass() )
-	-call its 'start' method (i.e. sim_program.start() )
-	"""
-
 	WRITE_DATA_FILES = False
 	DEBUG = False
 	PRINT_KEY_INFO = True
 
 	WINDOW_TITLE = "Autonomous Robot Simulator"
-	WINDOW_POSITION = (0,0)
-	WINDOW_SIZE = (1024,768) # (width,height)
+	WINDOW_POSITION = (0, 0)
+	WINDOW_SIZE = (1024, 768)  # (width,height)
 	WINDOW_ZOOM = 1.0
-	CAMERA_POSITION = (10,8,10)
+	CAMERA_POSITION = (10, 8, 10)
 
-	BACKGROUND_COLOR = (1,1,1)
+	BACKGROUND_COLOR = (1, 1, 1)
 
 	FPS = 50
 	STEPS_PER_FRAME = 50
 
-	FLOOR_BOX_SIZE = (10,0.01,10)
+	FLOOR_BOX_SIZE = (10, 0.01, 10)
 
 	def __init__(self):
-		"""
-		Constructor. Defines some attributes and calls some initialization
+		"""Constructor. Defines some attributes and calls some initialization
 		methods to:
-		-sets the basic mapping of key to action
-		-create the visualization window according to the related Program's
-		class constants
-		-create the simulation
+		-sets the basic mapping of key to action,
+		-create the visualization window according to class constants,
+		-create the simulation.
+
 		"""
 		self.do_create_window = True
-		self.data_files_names = None # TODO
-		self.data_files = None # TODO
+		self.data_files_names = None 	# TODO
+		self.data_files = None 			# TODO
 
 		self.key_press_functions = None
 		self.sim = None
 		self.set_key_2_action_mapping()
 
 		self.gAdapter = gp.VtkAdapter()
-		self.gAdapter.create_window(self.WINDOW_TITLE, self.WINDOW_POSITION, self.WINDOW_SIZE,
-							 zoom=self.WINDOW_ZOOM, background_color=self.BACKGROUND_COLOR,
-							 cam_position=self.CAMERA_POSITION)
+		self.gAdapter.create_window(self.WINDOW_TITLE,
+			self.WINDOW_POSITION,
+			self.WINDOW_SIZE,
+			zoom=self.WINDOW_ZOOM,
+			background_color=self.BACKGROUND_COLOR,
+			cam_position=self.CAMERA_POSITION)
 
 		self.create_simulation()
 
 	def start(self):
+		"""Starts (indirectly) the simulation handled by this class by starting
+		the visualization window. If it is closed, the simulation ends. It will
+		restart if :attr:`do_create_window` has been previously set to ``True``.
+
 		"""
-		Starts (indirectly) the simulation handled by this class by starting
-		the visualization window. If it is closed, the simulation ends. It will
-		restart if the 'do_create_window' has been previously set to True.
-		"""
-
-		if self.WRITE_DATA_FILES: self.sim.data_files = self.open_files()
+		if self.WRITE_DATA_FILES:
+			self.sim.data_files = self.open_files()
 
 		while self.do_create_window:
 			self.do_create_window = False
-			self.gAdapter.start_window(self.sim.on_idle, self.reset_simulation, self.on_action_selection)
+			self.gAdapter.start_window(self.sim.on_idle, self.reset_simulation,
+				self.on_action_selection)
 
 		# after the window is closed
-		if self.WRITE_DATA_FILES: self.close_files(self.sim.data_files)
+		if self.WRITE_DATA_FILES:
+			self.close_files(self.sim.data_files)
 
 	def reset_simulation(self):
 		"""Resets the simulation by resetting the graphics adapter and creating
-		a new simulation"""
+		a new simulation.
+
+		"""
 		if self.PRINT_KEY_INFO:
 			print("reset simulation")
 		self.do_create_window = True
 		self.create_simulation()
 
 	def create_simulation(self, add_axes=True, add_floor=True):
-		"""
-		Creates an empty simulation and:
-		-adds basic simulation objects ('add_basic_simulation_objects' method)
-		-(if `add_axes` is True) adds axes to the visualization at the coordinates-system origin
-		-(if `add_floor` is True) adds a floor with a defined normal vector and some visualization
-		parameters
-		-calls the 'create_sim_objects' method which must be implemented by
-		subclasses
+		"""Creates an empty simulation and:
+		-adds basic simulation objects (:meth:`add_basic_simulation_objects`),
+		-(if ``add_axes`` is ``True``) adds axes to the visualization at the
+		coordinates-system origin,
+		-(if ``add_floor`` is ``True``) adds a floor with a defined normal
+		vector and some visualization parameters,
+		-calls :meth:`create_sim_objects` (which must be implemented by
+		subclasses),
 		-gets the actors representing the simulation objects and adds them to
-		the graphics adapter
+		the graphics adapter.
+
 		"""
 		# set up the simulation parameters
 		self.sim = Simulation(self.FPS, self.STEPS_PER_FRAME)
 		if add_axes:
 			self.sim.add_axes()
 		if add_floor:
-			self.sim.add_floor(normal=(0,1,0), box_size=self.FLOOR_BOX_SIZE,
-				color=(0.7,0.7,0.7))
+			self.sim.add_floor(normal=(0, 1, 0), box_size=self.FLOOR_BOX_SIZE,
+				color=(0.7, 0.7, 0.7))
 
 		self.create_sim_objects()
 
 
 	@abstractmethod
 	def create_sim_objects(self):
-		"""
-		This method must be overriden (at least once in the inheritance tree)
+		"""This method must be overriden (at least once in the inheritance tree)
 		by the subclass that will instatiated to run the simulator.
 		It shall contain statements calling its 'sim' attribute's methods for
 		adding objects (e.g. add_sphere). For example:
 		self.sim.add_sphere(0.5, (1,10,1), density=1)
+
 		"""
 		raise NotImplementedError()
 
 	def set_key_2_action_mapping(self):
+		"""Creates an Action map, assigns it to :attr:`key_press_functions`
+		and then adds some ``(key, function`` tuples.
+
 		"""
-		Creates an Action map, assigns it to the 'key_press_functions'
-		attribute and then adds some pairs of 'key' and 'function'.
-		"""
-		self.key_press_functions = ActionMap() # TODO: add to constructor = None?
+		# TODO: add to constructor ``self.key_press_functions = None``?
+		self.key_press_functions = ActionMap()
 		self.key_press_functions.add('plus', self.select_next_joint)
 		self.key_press_functions.add('minus', self.select_previous_joint)
 		self.key_press_functions.add('r', self.reset_simulation)
 		self.key_press_functions.add('b', self.dec_joint_pos)
 
 	def on_action_selection(self, key):
-		"""Method called after an actions is selected by pressing a key"""
+		"""Method called after an actions is selected by pressing a key."""
 		if self.PRINT_KEY_INFO:
 			print(key)
 		try:
 		except Exception as ex:
 			print(ex)
 
-#===============================================================================
-# KEYPRESS action functions
-#===============================================================================
+	#==========================================================================
+	# KEYPRESS action functions
+	#==========================================================================
 
 	def select_next_joint(self):
 		"""select next joint for future user actions"""
 		"""decrement the position of an already selected joint"""
 		print('dec_joint_pos has not been implemented yet')
 
-
-#===============================================================================
-# FILES methods
-#===============================================================================
+	#==========================================================================
+	# FILES methods
+	#==========================================================================
 
 	def read_filenames(self):
 		print('read_filenames has not been implemented')
 		for _key in files:
 			files[_key].close()
 
-#===============================================================================
-# other
-#===============================================================================
+	#==========================================================================
+	# other
+	#==========================================================================
 
 	def on_pre_step(self):
-		"""
-		This method will be called before each integration step of the simulation.
+		"""This method will be called before each integration step of the simulation.
 		It is meant to be, optionally, implemented by subclasses.
+
 		"""
 		raise NotImplementedError()
 
 	def on_pre_frame(self):
-		"""
-		This method will be called before each visualization frame is created.
+		"""This method will be called before each visualization frame is created.
 		It is meant to be, optionally, implemented by subclasses.
+
 		"""
 		raise NotImplementedError()
 
 	def create_screenshot_recorder(self, base_filename, periodically=False):
+		"""Create a screenshot (of the frames displayed in the graphics window)
+		recorder.
+		
+		Each image will be written to a numbered file according to
+		``base_filename``. By default it will create an image each time
+		:meth:`record_frame` is called. If ``periodically`` is ``True`` then
+		screenshots will be saved in sequence. The time period between each
+		frame is determined according to :attr:`FPS`.
+
 		"""
-		Creates an screenshot (of the frames displayed in the graphics window) recorder.
-		Each image will be written to a numbered file according to 'base_filename'.
-		By default it will create an image each time 'record_frame' is called.
-		If 'periodically' is True then screenshots will be saved in sequence.
-		The time period between each frame is determined according to the FPS attribute
-		"""
-		self._screenshot_recorder = gp.ScreenshotRecorder(base_filename, self.gAdapter)
+		self._screenshot_recorder = gp.ScreenshotRecorder(base_filename,
+			self.gAdapter)
 		if periodically:
 			period = 1.0 / self.FPS
 			self._screenshot_recorder.period = period
 		dispatcher.connect(self.record_frame, signals.SIM_PRE_FRAME)
 
 	def record_frame(self):
-		"""
-		Records a frame using a screenshot recorder. If frames are meant to be
-		written periodically, a new one will be recorded only if enough time
-		has elapsed, otherwise it will return False. The filename index will be
-		time / period.
-		If frames are not meant to be written periodically, then index =
+		"""Record a frame using a screenshot recorder.
+		
+		If frames are meant to be written periodically, a new one will be
+		recorded only if enough time has elapsed, otherwise it will return
+		``False``. The filename index will be ``time / period``.
+		
+		If frames are not meant to be written periodically, then index equals
 		simulator's frame number.
+
 		"""
 		if self._screenshot_recorder is None:
 			raise exc.ArsError('Screenshot recorder is not initialized')
 		except Exception:
 			raise exc.ArsError('Could not record frame')
 
+
 class ActionMap:
 	def __init__(self):
 		self._map = {}
 
 	def add(self, key, value, repeat=False):
-		self._map[key] = (value,repeat)
+		self._map[key] = (value, repeat)
 
 	def has_key(self, key):
 		return self._map.has_key(key)
 
 
 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
+	pass

File ars/utils/mathematical.py

-
-# Created on 2011.08.09
-#
-# @author: german
-
-# TODO:	attribute the code sections that were taken from somewhere else
-
 """
 Functions to perform operations over vectors and matrices;
 deal with homogeneous transforms; convert angles and other structures.
 
 import generic as gut
 
-#===============================================================================
-# rotation directions are named by the third (z-axis) row of the 3x3 matrix, because ODE capsules
-# are oriented along the Z-axis
-#===============================================================================
+# TODO:	attribute the code sections that were taken from somewhere else
+
+#==============================================================================
+# rotation directions are named by the third (z-axis) row of the 3x3 matrix,
+# because ODE capsules are oriented along the Z-axis.
+#==============================================================================
 
 rightRot = (0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0)
 leftRot = (0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0)
 bkwdAxis = Z_AXIS  # direction: out of the screen
 fwdAxis = Z_AXIS_NEG  # direction: into the screen
 
-#===============================================================================
+#==============================================================================
 # added to the original refactored code
-#===============================================================================
+#==============================================================================
+
 
 def radians_to_degrees(radians_):
 	return degrees(radians_)
 
+
 # TODO: combine with the corresponding scalar-argument function
 def vec3_radians_to_degrees(vector_):
 	result = []
 		result.append(radians_to_degrees(radians_))
 	return tuple(result)
 
+
 def degrees_to_radians(degrees_):
 	return radians(degrees_)
 
+
 # TODO: combine with the corresponding scalar-argument function
 def vec3_degrees_to_radians(vector_):
 	result = []
 		result.append(degrees_to_radians(degrees_))
 	return tuple(result)
 
+
 def matrix3_multiply(matrix1, matrix2):
-	"""returns the matrix multiplication of matrix1 and matrix2"""
-	#TODO: check objects are valid, or use exceptions to catch errors raised by numpy
+	"""Return the matrix multiplication of ``matrix1`` and ``matrix2``."""
+	# TODO: check objects are valid, or use exceptions to catch errors raised
+	# by numpy
 
 	a1 = np.array(matrix1)
 	a2 = np.array(matrix2)
 
 	return matrix_as_3x3_tuples(tuple(result.flatten()))
 
+
 def matrix_as_tuple(matrix_):
-	"""\matrix_: nested tuples, e.g. ((1,0),(1,1),(2,5))"""
+	"""Convert ``matrix_`` to a tuple.
+
+	:param matrix_:
+	:type matrix_: nested tuples, e.g. ((1,0),(1,1),(2,5))
+
+	"""
 	#TODO: improve a lot
 	return gut.nested_iterable_to_tuple(matrix_)
 
+
 def matrix_as_3x3_tuples(tuple_9):
 	#TODO: improve a lot
 
 			matrix = (tuple_9[0:3], tuple_9[3:6], tuple_9[6:9])
 	return matrix
 
+
 def calc_acceleration(time_step, vel0, vel1):
-	"""Calculate the vectorial substraction `vel1` minus `vel0` divided by the
-	time step. If any of the vectors is `None`, then `None` is returned.
+	"""Calculate the vectorial substraction ``vel1 - vel0`` divided by
+	``time step``. If any of the vectors is ``None``, then ``None`` is returned.
 
-	`vel1` is the velocity measured `time_step` seconds after `vel0`.
+	``vel1`` is the velocity measured ``time_step`` seconds after ``vel0``.
 
 	"""
 	if vel0 is None or vel1 is None:
 
 
 def vector_matrix_vector(vector_, matrix_):
-	r"""Return the product of a transposed vector, a matrix and the same vector
-	again, which is a scalar value.
+	r"""Return the product of ``vector_`` transposed, ``matrix_`` and
+	``vector`` again, which is a scalar value.
 
 	.. math::
 		v^\top \mathbf{M} v
 	return np.dot(np.dot(np.array(vector_).T, np.array(matrix_)),
 		np.array(vector_))
 
-#===============================================================================
+#==============================================================================
 # Original code but formatted and some refactor
-#===============================================================================
+#==============================================================================
+
 
 def sign(x):
-	"""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
+	"""Return ``1.0`` if ``x`` is positive, ``-1.0`` otherwise."""
+	if x > 0.0:
+		return 1.0
+	else:
+		return -1.0
+
 
 def length2(vector):
-	"""Returns the length of a 2-dimensions vector"""
-	return sqrt(vector[0]**2 + vector[1]**2)
+	"""Return the length of a 2-dimension ``vector``."""
+	return sqrt(vector[0] ** 2 + vector[1] ** 2)
+
 
 def length3(vector):
-	"""Returns the length of a 3-dimensions vector"""
+	"""Return the length of a 3-dimension ``vector``."""
 	#TODO: convert it so it can handle vector of any dimension
-	return sqrt(vector[0]**2 + vector[1]**2 + vector[2]**2)
+	return sqrt(vector[0] ** 2 + vector[1] ** 2 + vector[2] ** 2)
+
 
 def neg3(vector):
-	"""Returns the negation of 3-vector vector"""
+	"""Return the negation of 3-dimension ``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"""
+	"""Return the sum of 3-dimension ``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])
+	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"""
+	"""Return the difference between 3-dimension ``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])
+	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"""
+	"""Return 3-dimension ``vector`` multiplied by ``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"""
+	"""Return 3-dimension ``vector`` divided by ``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"""
+	"""Return the distance between point 3-dimension ``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"""
+	"""Return the unit length vector parallel to 3-dimension ``vector``."""
 	#l = length3(vector)
 	#if l > 0.0:
 	#	return (vector[0] / l, vector[1] / l, vector[2] / l)
 	#	return (0.0, 0.0, 0.0)
 	return unitize(vector)
 
+
 def unitize(vector_):
-	"""Unitize a vector, i.e. return a unit-length vector parallel to `vector`
+	"""Unitize a vector, i.e. return a unit-length vector parallel to
+	``vector``.
 
 	"""
 	len_ = sqrt(sum(itertools.imap(operator.mul, vector_, vector_)))
 	else:
 		return (0.0, 0.0, 0.0)
 
+
 def dot_product3(vector1, vector2):
-	"""Returns the dot product of 3-vectors vector1 and vector2"""
+	"""Return the dot product of 3-dimension ``vector1`` and ``vector2``."""
 	return dot_product(vector1, vector2)
 
+
 def dot_product(vec1, vec2):
 	"""Efficient dot-product operation between two vectors of the same size.
 	source: http://docs.python.org/library/itertools.html
 	"""
 	return sum(itertools.imap(operator.mul, vec1, vec2))
 
+
 def cross_product(vector1, vector2):
-	"""Returns the cross_product product of length-3 vectors `vector1` and
-	`vector2`
-
-	"""
+	"""Return the cross product of 3-dimension ``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"""
+	"""Return projection of 3-dimension ``vector`` onto unit 3-dimension
+	``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"""
+	"""Return the angle between unit 3-dimension ``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)
+	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"""
-	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])
+	"""Return the rotation of 3-dimension ``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"""
+	"""Return 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"""
+	"""Return 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])
 
-#===============================================================================
+#==============================================================================
 # TESTS
-#===============================================================================
+#==============================================================================
+
 
 def _test_angular_conversions(angle_):
 	#x = 2.0/3*pi

File docs/sphinx/source/apidoc/ars.gui.rst

-gui Package
-===========
-
-:mod:`gui` Package
-------------------
-
-.. automodule:: ars.gui
-    :members:
-    :undoc-members:
-    :show-inheritance:
-

File docs/sphinx/source/apidoc/ars.model.robot.rst

     :undoc-members:
     :show-inheritance:
 
-:mod:`actuators` Module
------------------------
-
-.. automodule:: ars.model.robot.actuators
-    :members:
-    :undoc-members:
-    :show-inheritance:
-
 :mod:`joints` Module
 --------------------
 

File docs/sphinx/source/apidoc/ars.rst

 
     ars.app
     ars.graphics
-    ars.gui
     ars.lib
     ars.model
     ars.utils