Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[services] Add a service to replace the texture of an object #798

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ option(BUILD_HLA_SUPPORT "Build HLA middleware support. Also used for distribute
option(PYMORSE_SUPPORT "Build and install the Python bindings for MORSE." ON)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/config/)
find_package(PkgConfig REQUIRED)
IF(NOT WIN32)
find_package(PkgConfig REQUIRED)
endif(NOT WIN32)

set(PythonInterp_FIND_VERSION 3.3)
find_package(PythonInterp REQUIRED)
Expand Down
31 changes: 28 additions & 3 deletions INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ distributions.

Other UNIXes systems probably work as well (like FreeBSD or Apple MacOSX).

MORSE does not currently officially support Microsoft Windows, although some
users reported success. Testers/maintainers for Windows are welcome!
Windows is supported, but not fully tested.

Packaged versions
-----------------
Expand Down Expand Up @@ -94,15 +93,21 @@ Prerequisites
- python-dev package
- Blender (>= 2.65) build with Python >= 3.3. You can simply get a binary from
Blender website

If building on Windows, ensure that your Python version and architecture matches
the bundled Python in Blender (currently Python 3.5.3 for Blender 2.79).


Installation
++++++++++++

Linux
-----

Download the latest version of the source code. It is stored in a git
repository::

$ git clone https://github.com/laas/morse.git
$ git clone https://github.com/morse-simulator/morse.git

You can also get a tarball version here.

Expand Down Expand Up @@ -168,6 +173,26 @@ When updating MORSE to a more recent version, you'll simply have to do::
$ cd build
$ make install

Windows
-------

Download the latest version of the source code. It is stored in a git
repository::

$ git clone https://github.com/morse-simulator/morse.git

The MORSE_BLENDER environment variable should be set to the location and filename
of the Blender executable (ie "C:\Program Files\Blender\blender.exe").

Additionally, both cmake and Python should be on the system path.

Go to the directory where you have previously downloaded the MORSE source.
Then run the winbuild.bat script.

By default, MORSE will install in C:\morse. You can easily change the
install directory by editing the MORSE_ROOT variable in
winbuild.bat

Installation troubleshooting
----------------------------

Expand Down
1 change: 1 addition & 0 deletions RELEASE_NOTES
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ General
compute automatically the right time settings. If you meet any problem
related to time, make sure to read the Time and Event documentation and / or
report issue to the Morse project.
- Windows is now supported for building MORSE and running the unit test suite.

Components
----------
Expand Down
6 changes: 3 additions & 3 deletions doc/morse/dev/services_internal.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Asynchronous services

Registration of asynchronous services is almost the same as for synchronous
services. The ``@async_service`` decorator simply calls the ``@service``
decorator with the ``async`` parameter set to ``True``, which results in
decorator with the ``asynchronous`` parameter set to ``True``, which results in
the original method being wrapped in a new method that takes an extra parameter
(a callback) and calls
:py:meth:`morse.core.abstractobject.AbstractObject.set_service_callback`.
Expand All @@ -74,9 +74,9 @@ Simplified version of the ``@service`` decorator:

.. code-block:: python

def service(fn, async=False):
def service(fn, asynchronous=False):
dfn = fn
if async:
if asynchonous:
def decorated_fn(self, callback, *param):
self._set_service_callback(callback)
fn(self, *param)
Expand Down
2 changes: 2 additions & 0 deletions doc/morse/dev/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ This will start launching MORSE with a series of unit tests, to check that
the creation of scenes and some of the components is running properly on your
system.

Windows users can run the ``winbuild.bat`` file to build and run the tests
automatically.


Running tests
Expand Down
29 changes: 27 additions & 2 deletions doc/morse/user/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ It should also work on UNIX systems more generally, such as FreeBSD and Apple Ma
Some successful testing has been done on OSX 10.8 (see
below for the Homebrew recipe).

As yet, there is no official support for Microsoft Windows, although some
users have reported success. Testers/maintainers for Windows are welcome!
Windows is supported, but not fully tested.


Hardware
Expand Down Expand Up @@ -121,9 +120,15 @@ Prerequisites
.. note::
If you use a Blender binary, numpy is included within it.

.. note::
If building on Windows, ensure that your Python version and architecture matches
the bundled Python in Blender (currently Python 3.5.3 for Blender 2.79).

Installation
++++++++++++

Linux
-----

Clone with ``git`` or download the latest version of the source code::

Expand Down Expand Up @@ -161,6 +166,26 @@ You can check your configuration is okay with::
Once MORSE is successfully installed and checked you are read for the
:doc:`Quickstart<../quickstart>` tutorial!

Windows
-------

Download the latest version of the source code. It is stored in a git
repository::

$ git clone https://github.com/morse-simulator/morse.git

The MORSE_BLENDER environment variable should be set the the location and filename
of the Blender executable (ie "C:\Program Files\Blender\blender.exe").

Additionally, both cmake and Python should be on the system path.

Go to the directory where you have previously downloaded the MORSE source.
Then run the winbuild.bat script.

By default, MORSE will install in C:\morse. You can easily change the
install directory by editing the MORSE_ROOT variable in
``winbuild.bat``

Middleware-specific notes
+++++++++++++++++++++++++

Expand Down
2 changes: 1 addition & 1 deletion src/morse/builder/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@
"ros": 'morse.middleware.ros.force_torque.WrenchReader',
}
},
"morse.actuators.externalForce.ExternalForce": {
"morse.actuators.external_force.ExternalForce": {
"default": {
"socket": INTERFACE_DEFAULT_IN,
"yarp": INTERFACE_DEFAULT_IN,
Expand Down
9 changes: 5 additions & 4 deletions src/morse/builder/sensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def __init__(self, name=None):
mesh.scale = (.04, .04, .02)
mesh.color(.3, .9, .6)
self.append(mesh)

class Magnetometer(SensorCreator):
_classpath = "morse.sensors.magnetometer.Magnetometer"

Expand Down Expand Up @@ -476,18 +476,19 @@ def __init__(self, name=None):
for i in range(3):
cam = DepthCamera("cam%i"%i)
"""
cam_focal = 27.7 => hfov ~= 60.0.
cam_focal = 27.7 => hfov ~= 60.0.
As cam_height is half the cam_width, vfov ~= 30.0, so each pixel represent around 0.117°
Hence, the keep_list is a reasonnably fair approximation of the real angle of VLP16
"""
cam.properties(cam_width=512, cam_height=256, cam_focal = 27.7,
keep_list=str([0, 17, 34, 51, 68, 85, 102, 120, 137, 154, 171, 188, 205, 222, 239, 256]))
keep_list=str([1, 17, 34, 51, 68, 85, 102, 120, 137, 154, 171, 188, 205, 222, 239, 255]),
keep_resolution=True)
cam.rotate(x=(i-1) * math.pi / 3)
cam.frequency(10)
cam.hide_mesh()
self.append(cam)

self.append_meshes(['VelodyneMesh'])
# self.append_meshes(['VelodyneMesh'])
self.set_master(1)

def after_renaming(self):
Expand Down
5 changes: 5 additions & 0 deletions src/morse/core/blenderapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ def constraints():
else:
return None

def app():
if not fake:
return bge.app
else:
return None

def texture():
if not fake:
Expand Down
12 changes: 6 additions & 6 deletions src/morse/core/request_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def complex_computation(result_setter, param1, param2):
self.register_service(component_name, callback, service_name, True)


def register_service(self, component_name, callback, service_name = None, async = False):
def register_service(self, component_name, callback, service_name = None, asynchronous = False):
""" Allows a component to register a synchronous RPC method that is made
publicly available to the outside world.

Expand All @@ -146,10 +146,10 @@ def register_service(self, component_name, callback, service_name = None, async
request.
If service_name is not defined, it will also be used as
the public name of the service.
If async is false (synchronous service), the method is expected to
If asynchronous is false (synchronous service), the method is expected to
return immediately. In this case, its return value is immediately
send back to the original caller.
:param boolean async: if true, the service is asynchronous: it can last for
:param boolean asynchronous: if true, the service is asynchronous: it can last for
several cycles without blocking the communication interface.
See :py:meth:`register_async_service` for details.
:param service_name: if defined, service_name is used as public
Expand All @@ -159,11 +159,11 @@ def register_service(self, component_name, callback, service_name = None, async
if hasattr(callback, '__call__'):
service_name = service_name if service_name else callback.__name__

self._services[(component_name, service_name)] = (callback, async)
self._services[(component_name, service_name)] = (callback, asynchronous)

if self.post_registration(component_name, service_name, async):
if self.post_registration(component_name, service_name, asynchronous):
logger.info(str(self) + ": " + \
("Asynchronous" if async else "Synchronous") + \
("Asynchronous" if asynchronous else "Synchronous") + \
" service '" + service_name + "' for component '" + \
component_name + "' successfully registered")
else:
Expand Down
20 changes: 10 additions & 10 deletions src/morse/core/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def process(self):
instance.process()


def do_service_registration(fn, component_name = None, service_name = None, async = False, request_managers = None):
def do_service_registration(fn, component_name = None, service_name = None, asynchronous = False, request_managers = None):

if blenderapi.fake: #doc mode
return
Expand All @@ -122,7 +122,7 @@ def do_service_registration(fn, component_name = None, service_name = None, asyn
for manager in request_managers:
name = service_name if service_name else fn.__name__
logger.debug("Registering service " + name + " in " + component_name + " (using " + manager.__class__.__name__ + ")")
manager.register_service(component_name, fn, name, async)
manager.register_service(component_name, fn, name, asynchronous)

def async_service(fn = None, component = None, name = None):
""" The @async_service decorator.
Expand All @@ -138,9 +138,9 @@ def async_service(fn = None, component = None, name = None):
explaining why the initialization failed.

"""
return service(fn, component, name, async = True)
return service(fn, component, name, asynchronous = True)

def service(fn = None, component = None, name = None, async = False):
def service(fn = None, component = None, name = None, asynchronous = False):
""" The @service decorator.

This decorator can be used to automagically register a service in
Expand All @@ -163,7 +163,7 @@ def service(fn = None, component = None, name = None, async = False):
functions. Cf explanation above.
:param string name: by default, the name of the service is the name
of the method. You can override it by setting the 'name' argument.
:param boolean async: if set to True (default value when using
:param boolean asynchronous: if set to True (default value when using
@async_service), a new 'callback' parameter is added to the method.
This callback is used to notify the service initiator that the service
completed. The callback does not need to be build manually:
Expand All @@ -180,7 +180,7 @@ def service(fn = None, component = None, name = None, async = False):
# this method as a service.
logger.debug("In @service: Decorating method "+ fn.__name__)
dfn = fn
if async:
if asynchronous:
def decorated_fn(self, callback, *param):
# Stores in the callback the original calling
# service.
Expand Down Expand Up @@ -210,22 +210,22 @@ def decorated_fn(self, callback, *param):

dfn._morse_service = True
dfn._morse_service_name = name
dfn._morse_service_is_async = async
dfn._morse_service_is_async = asynchronous

return dfn

else:
if async:
if asynchronous:
logger.warning("asynchronous service must be declared within a MorseObject class.")
return

logger.debug("In @service: Decorating free function "+ fn.__name__)
# We assume it's a free function, and we register it.
do_service_registration(fn, component, name, async)
do_service_registration(fn, component, name, asynchronous)
return fn
else:
# ...else, we build a new decorator
return partial(service, component = component, name = name, async = async)
return partial(service, component = component, name = name, asynchronous = asynchronous)

def interruptible(fn):
""" The @interruptible decorator.
Expand Down
6 changes: 3 additions & 3 deletions src/morse/middleware/ros_request_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,8 @@ class method to be a asynchronous service, exposed as a ROS action of
return partial(ros_action, type = type, name = name)

fn._ros_action_type = type
return services.service(fn, component = None, name = name, async = True)
return services.service(fn, component = None, name = name, asynchronous = True)


def ros_service(fn = None, type = None, component = None, name = None):
""" The @ros_service decorator.
Expand Down Expand Up @@ -433,4 +433,4 @@ class method to be a (synchronous) service, exposed as a ROS service of
return partial(ros_service, type = type, component = component, name = name)

fn._ros_service_type = type
return services.service(fn, component = component, name = name, async = False)
return services.service(fn, component = component, name = name, asynchronous = False)
6 changes: 5 additions & 1 deletion src/morse/sensors/depth_camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ class DepthCamera(AbstractDepthCamera):
"better simulate sparse sensor such as velodyne. If not specified, keep the "
"image dense")

add_property('_keep_resolution', False, 'keep_resolution', 'boolean',
"By default the clipping of the camera removes unreals points"
"This option allows adding dummy points (0,0,0) for keeping the sensor resolution")

def initialize(self):
from morse.sensors.zbufferto3d import ZBufferTo3D
if self._keep_list is None:
Expand All @@ -82,7 +86,7 @@ def initialize(self):
self.converter = ZBufferTo3D(self.local_data['intrinsic_matrix'][0][0],
self.local_data['intrinsic_matrix'][1][1],
self.near_clipping, self.far_clipping,
self.image_width, self.image_height,
self.image_width, self.image_height, self._keep_resolution,
keep_list)

def process_image(self, image):
Expand Down
4 changes: 0 additions & 4 deletions src/morse/sensors/depthaggregator.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include <Python.h>
#include "structmember.h"


typedef struct {
PyObject_HEAD
// The buffer to return values
Expand Down Expand Up @@ -59,9 +58,6 @@ Aggregator_merge(PyAggregator* self, PyObject* args)
int len = PyList_Size(listObj);
int j = 0;

struct timeval begin, end, res;
gettimeofday(&begin, NULL);

for (int i = 0; i < len; ++i)
{
float tx, ty, tz, rx, ry, rz;
Expand Down
Loading