Permalink
Browse files

First template for actuators

Test it with: morse add actuator <name> <env>

Demonstrate a synchronous service and an asynchronous one

Current implementation of default_action is not great (looks
more like a sensor)
  • Loading branch information...
Séverin Lemaignan authored and adegroote committed Apr 8, 2013
1 parent 5cca82b commit cab8b51ec84cdd0a979dfba90e362ba7e1284517
View
@@ -16,7 +16,7 @@ formatter = logging.Formatter("* %(message)s\n")
log_handler.setFormatter(formatter)
logger.addHandler(log_handler)
-logger.setLevel(logging.DEBUG)
+logger.setLevel(logging.INFO)
##
try:
@@ -539,7 +539,8 @@ def add_component(args):
except MorseEnvironmentError as e:
logger.error("%s" % e)
sys.exit(1)
- logger.info("A new %s called <%s> has been added to <%s>." % (type, name, args.env))
+
+ logger.debug("A new %s called <%s> has been added to <%s>." % (type, name, args.env))
def prelaunch():
@@ -0,0 +1,62 @@
+import logging; logger = logging.getLogger("morse." + __name__)
+
+import morse.core.actuator
+
+from morse.core.services import service, async_service, interruptible
+from morse.core import status
+from morse.helpers.components import add_data, add_property
+
+class @classname@(morse.core.actuator.Actuator):
+ _name = "@classname@"
+ _short_desc = "@shortdesc@"
+
+ # define here the data fields required by your actuator
+ # format is: field name, initial value, type, description
+ add_data('counter', 0, 'int', 'A dummy counter, for testing purposes')
+
+ def __init__(self, obj, parent=None):
+ logger.info("%s initialization" % obj.name)
+ # Call the constructor of the parent class
+ super(self.__class__, self).__init__(obj, parent)
+
+ # Do here actuator specific initializations
+
+ self._target_count = 0 # dummy internal variable, for testing purposes
+
+ logger.info('Component initialized')
+
+ @service
+ def get_counter(self):
+ """ This is a sample service.
+
+ Simply returns the value of the internal counter.
+
+ You can access it as a RPC service from clients.
+ """
+ logger.info("%s counter is %s" % (self.name, self.local_data['counter']))
+
+ return self.local_data['counter']
+
+ @interruptible
+ @async_service
+ def async_test(self, value):
+ """ This is a sample asynchronous service.
+
+ Returns when the internal counter reaches ``value``.
+
+ You can access it as a RPC service from clients.
+ """
+ self._target_count = value
+
+ def default_action(self):
+ """ Main loop of the actuator.
+
+ Implements the component behaviour
+ """
+
+ # check if we have an on-going asynchronous tasks...
+ if self._target_count and self.local_data['counter'] > self._target_count:
+ self.completed(status.SUCCESS, self.local_data['counter'])
+
+ # implement here the behaviour of your actuator
+ self.local_data['counter'] += 1
@@ -0,0 +1,8 @@
+from morse.builder.creator import ActuatorCreator
+
+class @classname@(ActuatorCreator):
+ def __init__(self, name=None):
+ ActuatorCreator.__init__(self, name, \
+ "@env@.actuators.@name@.@classname@",\
+ "@name@")
+
@@ -5,10 +5,12 @@ class @classname@(morse.core.robot.Robot):
""" Class definition for the @name@ robot."""
def __init__(self, obj, parent=None):
- """ Constructor method.
- Receives the reference to the Blender object.
- Optionally it gets the name of the object's parent,
- but that information is not currently used for a robot. """
+ """ Constructor method
+
+ Receives the reference to the Blender object.
+ Optionally it gets the name of the object's parent,
+ but that information is not currently used for a robot.
+ """
logger.info('%s initialization' % obj.name)
super(self.__class__,self).__init__(obj, parent)
View
@@ -62,8 +62,8 @@ def pyprint(code):
###################
NEW_ROBOT_MSG = ["""
-A template for a new robot called <{name}> has been added to the
-<{env}> environment.
+A template for a new robot called <{name}> has been
+added to the <{env}> environment.
----------------------------------------------------------
To complete the equipment of your robot, edit:
@@ -92,6 +92,59 @@ def pyprint(code):
Happy simulation!
"""]
+NEW_ACTUATOR_MSG = ["""
+A template for a new actuator called <{name}> has been
+added to the <{env}> environment.
+
+----------------------------------------------------------
+Edit {prefix}/src/actuators/{name}.py to implement the
+behaviour of your actuator.
+
+----------------------------------------------------------
+To use it on your robot, edit your robot description in
+{prefix}/src/builder/robots/
+and add these lines:
+
+""", ("""from {env}.builder.actuators import {classname}
+
+# create a new {name} actuator
+{name} = {classname}()
+
+robot.append({name})
+
+""", 'python'),
+"""----------------------------------------------------------
+Happy simulation!
+"""]
+
+NEW_SENSOR_MSG = ["""
+A template for a new sensor called <{name}> has been
+added to the <{env}> environment.
+
+----------------------------------------------------------
+Edit {prefix}/src/sensors/{name}.py to implement the
+behaviour of your sensor.
+
+----------------------------------------------------------
+To use it on your robot, edit your robot description in
+{prefix}/src/builder/robots/
+and add these lines:
+
+""", ("""from {env}.builder.sensors import {classname}
+
+# create a new {name} sensor
+{name} = {classname}()
+
+robot.append({name})
+
+""", 'python'),
+"""----------------------------------------------------------
+Happy simulation!
+"""]
+
+
+#################################################################
+
class Environment():
def __init__(self, morse_prefix, env_name, env_path = None):
@@ -223,7 +276,7 @@ def add_component(self, cmpttype, name):
safename = self._make_safe_name(name)
if safename != name:
- logger.warning("Replace name <%s> by suitable identifier: "
+ logger.warning("Replaced name <%s> by suitable identifier: "
"<%s>" % (name, safename))
if cmpttype == "robot":
@@ -238,8 +291,28 @@ def add_component(self, cmpttype, name):
classname = safename.capitalize(), \
env = self.env)
elif cmpttype == "sensor":
- self._install_files(SENSOR, name = safename)
+ desc = input("Enter a short description for sensor <%s>: " % safename)
+ self._install_files(SENSOR, \
+ name = safename, \
+ classname = safename.capitalize(), \
+ env = self.env, \
+ shortdesc = desc)
+ self._print_info_msg(NEW_SNESOR_MSG, \
+ prefix= self.abspath, \
+ name = safename, \
+ classname = safename.capitalize(), \
+ env = self.env)
elif cmpttype == "actuator":
- self._install_files(ACTUATOR, name = safename)
+ desc = input("Enter a short description for actuator <%s>: " % safename)
+ self._install_files(ACTUATOR, \
+ name = safename, \
+ classname = safename.capitalize(), \
+ env = self.env, \
+ shortdesc = desc)
+ self._print_info_msg(NEW_ACTUATOR_MSG, \
+ prefix= self.abspath, \
+ name = safename, \
+ classname = safename.capitalize(), \
+ env = self.env)
else:
raise MorseEnvironmentError("Unknown component type %s" % cmpttype)

0 comments on commit cab8b51

Please sign in to comment.