Source code for morse.sensors.stereo_unit

import logging; logger = logging.getLogger("morse." + __name__)
from morse.core.services import async_service
import morse.core.sensor
from morse.core import blenderapi
from functools import partial

[docs]class StereoUnit(morse.core.sensor.Sensor): """ The purpose of this component is to link together one or more cameras, and provide them with the possibility to move together as a single unit. It will also provide the connection interface to use the information of the cameras attached to it. In the case of two cameras, it will provide the stereo information generated from the two camera images. Related components ------------------ A stereo unit needs to be the parent of one or more :doc:`cameras <../sensors/video_camera>`. Otherwise, it does no useful function. The movement of the stereo unit is implemented by making it the child of a :doc:`Pan-Tilt unit <../actuators/ptu>` actuator. Here is an example of how to construct the whole stereo system to mount on top of a robot, using the Builder API. Note the order in which components are appended to each other, as this is important to get the desired functionality: .. code-block:: python from morse.builder import * # Add a robot atrv = ATRV() atrv.translate(z=0.1000) # A pan-tilt unit to be able to orient the cameras Platine = PTU() Platine.translate(x=0.2000, z=0.9000) atrv.append(Platine) # The STEREO UNIT, where the two cameras will be fixed Stereo = StereoUnit() Stereo.translate(z=0.0400) Platine.append(Stereo) # Left camera CameraL = VideoCamera() CameraL.translate(x=0.1000, y=0.2000, z=0.0700) Stereo.append(CameraL) CameraL.properties(capturing = True) CameraL.properties(cam_width = 320) CameraL.properties(cam_height = 240) CameraL.properties(cam_focal = 25.0000) # Right camera CameraR = VideoCamera() CameraR.translate(x=0.1000, y=-0.2000, z=0.0700) Stereo.append(CameraR) CameraR.properties(capturing = True) CameraR.properties(cam_width = 320) CameraR.properties(cam_height = 240) CameraR.properties(cam_focal = 25.0000) """ _name = "Stereo Camera Unit" def __init__(self, obj, parent=None): """ Constructor method. Receives the reference to the Blender object. The second parameter should be the name of the object's parent. """ logger.info('%s initialization' % obj.name) # Call the constructor of the parent class morse.core.sensor.Sensor.__init__(self, obj, parent) self.num_cameras = 0 self.camera_list = [] # Create a list of the cameras attached to this component for child in obj.children: # Skip this object if it is not a component # It is most likely just a geometric shape object try: child['Component_Tag'] except KeyError: continue camera_name = child.name # Store only the name of the camera All data from the camera # can be accessed later by using # blenderapi.persistantstorage().componentDict[camera_name], # which will return the instance of the camera object self.camera_list.append(camera_name) self.num_cameras += 1 logger.info("Stereo Unit has %d cameras" % self.num_cameras) logger.info('Component initialized')
[docs] def capture_completion(self, answer): self._expected_answer-= 1 if self._expected_answer == 0: status, res = answer self.completed(status, res)
[docs] def interrupt(self): for camera in self.camera_list: camera_instance = blenderapi.persistantstorage().componentDict[camera] camera_instance.interrupt()
@async_service def capture(self, n): """ The service takes an integer an argument and dispatch the call to all its individual cameras. The service ends when each camera has terminated its work. :param n: the number of call to each individual camera """ self._expected_answer = self.num_cameras for camera in self.camera_list: camera_instance = blenderapi.persistantstorage().componentDict[camera] camera_instance.capture(partial(self.capture_completion), n)
[docs] def default_action(self): """ Main function of this component. """ pass