Skip to content

Commit

Permalink
First template for actuators
Browse files Browse the repository at this point in the history
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 Arnaud Degroote committed Apr 10, 2013
1 parent 5cca82b commit cab8b51
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 11 deletions.
5 changes: 3 additions & 2 deletions bin/morse.in
Expand Up @@ -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:
Expand Down Expand Up @@ -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():
Expand Down
62 changes: 62 additions & 0 deletions data/templates/src/@env@/actuators/@name@.py.tpl
@@ -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
8 changes: 8 additions & 0 deletions data/templates/src/@env@/builder/actuators/@name@.py.tpl
@@ -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@")

10 changes: 6 additions & 4 deletions data/templates/src/@env@/robots/@name@.py.tpl
Expand Up @@ -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)
Expand Down
83 changes: 78 additions & 5 deletions src/morse/environments.py
Expand Up @@ -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:
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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":
Expand All @@ -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.