Source code for morse.core.object

import logging; logger = logging.getLogger("morse." + __name__)
from abc import ABCMeta, abstractmethod
from morse.core.abstractobject import AbstractObject

import morse.helpers.transformation
from morse.core.services import service

from morse.core import blenderapi

[docs]class Object(AbstractObject): """ Basic Class for all 3D objects (components) used in the simulation. Provides common attributes. """ # Make this an abstract class __metaclass__ = ABCMeta def __init__ (self, obj, parent=None): super(Object, self).__init__() # Fill in the data sent as parameters self.bge_object = obj self.robot_parent = parent self.level = self.bge_object.get("abstraction_level", "default") # Variable to indicate the activation status of the component self._active = True self.check_level() # Define the position of sensors with respect # to their robot parent # TODO: implement this using morse.helpers.transformation if parent: self.relative_position = obj.getVectTo(parent.bge_object) # Create an instance of the 3d transformation class self.position_3d = morse.helpers.transformation.Transformation3d(obj) self.initialize_local_data() self.update_properties() # The actual frequency at which the action is called # The frequency of the game sensor specifies how many times # the action is skipped when the logic brick is executed. # e.g. game sensor frequency = 0 -> sensor runs at full logic rate sensors = blenderapi.getalwayssensors(obj) self._frequency = blenderapi.getfrequency() # New MORSE_LOGIC sensor, see AbstractComponent.morseable() morselogic = [s for s in sensors if s.name.startswith('MORSE_LOGIC')] if len(morselogic) == 1: self._frequency /= morselogic[0].frequency + 1 # Backward compatible (some actuators got special logic) elif len(sensors) == 1: self._frequency /= sensors[0].frequency + 1 elif len(sensors) == 0: logger.warning("Can't get frequency for " + self.name() + \ " as the Game Logic sensor calling the action can't be found.") else: logger.warning(self.name() + " has too many Game Logic sensors to get " + \ "an unambiguous frequency for the action.")
[docs] def check_level(self): if self.level == "default": return # fine if hasattr(self, '_levels') and self.level in self._levels: return #fine msg = "Component <%s> has no abstraction level <%s>. Please check your scene." % (self.name(), self.level) logger.error(msg) raise ValueError(msg)
[docs] def initialize_local_data(self): """ Creates and initializes 'local data' fields, according to the current component abstraction level. """ if hasattr(self, '_data_fields'): for name, details in self._data_fields.items(): default_value, type, doc, level = details if level == "all" or level == self.level: self.local_data[name] = default_value
[docs] def update_properties(self): """ Takes all registered properties (see add_property), and update their values according to the values set in Blender object. """ if hasattr(self, '_properties'): for name, details in self._properties.items(): default_value, type, doc, python_name = details val = default_value try: val = self.bge_object[name] except KeyError: pass setattr(self, python_name, val)
[docs] def name(self): return self.bge_object.name
[docs] def action(self): """ Call the regular action function of the component. Can be redefined in some of the subclases (sensor and actuator). """ self.default_action()
@abstractmethod
[docs] def default_action(self): """ Base action performed by any object. This method should be implemented by all subclasses that will be instanced (GPS, v_Omega, ATRV, etc.). """ pass
[docs] def toggle_active(self): self._active = not self._active
@property
[docs] def frequency(self): """ Frequency of the object action in Hz (float). """ return self._frequency