camera.py
Go to the documentation of this file.
00001 # Software License Agreement (BSD License)
00002 #
00003 # Copyright (c) 2010, Willow Garage, Inc.
00004 # All rights reserved.
00005 #
00006 # Redistribution and use in source and binary forms, with or without
00007 # modification, are permitted provided that the following conditions
00008 # are met:
00009 #
00010 #  * Redistributions of source code must retain the above copyright
00011 #    notice, this list of conditions and the following disclaimer.
00012 #  * Redistributions in binary form must reproduce the above
00013 #    copyright notice, this list of conditions and the following
00014 #    disclaimer in the documentation and/or other materials provided
00015 #    with the distribution.
00016 #  * Neither the name of Willow Garage, Inc. nor the names of its
00017 #    contributors may be used to endorse or promote products derived
00018 #    from this software without specific prior written permission.
00019 #
00020 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 # POSSIBILITY OF SUCH DAMAGE.
00032 #
00033 # Revision $Id: camera.py 11372 2010-10-01 20:52:44Z kwc $
00034 
00035 from __future__ import with_statement
00036 
00037 PKG = 'rosh_common'
00038 # we define this in the rosh_common package because the camera data
00039 # representation is part of common_msgs
00040 
00041 import os
00042 import sys
00043 import time
00044 
00045 import roslib.names
00046 import roslib.packages
00047 
00048 import rosh #for get_topics()
00049 import rosh.impl.proc
00050 import rosh.impl.topic
00051 
00052 from rosh.impl.namespace import Namespace, Concept
00053     
00054 _TIMEOUT_CAM_INFO = 3
00055 
00056 class Camera(Namespace):
00057 
00058     def __init__(self, name, config):
00059         """
00060         ctor.
00061         @param config: Namespace configuration instance with additional 'listener' attribute. 
00062         @type  config: L{NamespaceConfig}
00063         """
00064         super(Camera, self).__init__(name, config)
00065         self._cam_info = None
00066             
00067     def _list(self):
00068         """
00069         Override Namespace._list()
00070         """
00071         try:
00072             pubs = self._config.master.getPublishedTopics(self._ns)
00073             candidates = [p[0] for p in pubs if p[0].endswith('/image_raw')]
00074             pub_names = [p[0] for p in pubs]
00075             matches = []
00076             for c in candidates:
00077                 stem = c[:-len('image_raw')]
00078                 if stem and stem+'camera_info' in pub_names:
00079                     matches.append(stem)
00080             return matches
00081         except:
00082             return []
00083 
00084     def __repr__(self):
00085         return self.__str__()
00086         
00087     def __str__(self):
00088         # TODO: camera info?
00089         if self._cam_info is None:
00090             self._init_cam_info()
00091         if self._cam_info is None:
00092             return self._ns
00093         else:
00094             return str(self._cam_info)
00095 
00096     def _init_cam_info(self):
00097         if self._ns == '/':
00098             return
00099         
00100         if self._cam_info is None:
00101             # this is a bit ugly. need cleaner/level-consistent API for rosh.impl.topic access
00102             try:
00103                 ns_obj = rosh.get_topics()[roslib.names.ns_join(self._ns, 'camera_info')]
00104                 self._cam_info = rosh.impl.topic.next_msg(ns_obj, _TIMEOUT_CAM_INFO)
00105             except:
00106                 pass
00107 
00108     def __call__(self, *args, **kwds):
00109         """
00110         Poll image from camera.
00111         
00112         @return: current transform
00113         @rtype: L{Transform}
00114         """
00115         ns_obj = rosh.get_topics()[self._ns]
00116         return rosh.impl.topic.next_msg(ns_obj)
00117 
00118     def _show(self):
00119         return self._config.ctx.rosh_common__show_handler(self)
00120 
00121 class Cameras(Concept):
00122 
00123     def __init__(self, ctx, lock):
00124         ctx.rosh_common__show_handler = show_camera_py_image_view
00125         super(Cameras, self).__init__(ctx, lock, Camera)
00126 
00127     def _register_show_handler(self, handler):
00128         self._config.ctx.rosh_common__show_handler = handler
00129 
00130 def show_camera_py_image_view(ns_obj):
00131     """
00132     Default show camera handler that uses
00133     py_image_view. rosh_visualization provides an optimized rviz-based
00134     viewer.
00135 
00136     TODO: 
00137     @return: image viewer node (if single camera), or tuple of image viewer nodes (if stereo)
00138     @rtype: Node or (Node, Node)
00139     """
00140 
00141     if ns_obj._cam_info is None:
00142         # check to see if it's stereo
00143         l = ns_obj._getAttributeNames()
00144         if 'left' in l and 'right' in l:
00145             n1 = show_camera_py_image_view(ns_obj.left)
00146             n2 = show_camera_py_image_view(ns_obj.right)
00147             return n1, n2
00148         else:
00149             # NOTE: this will block
00150             try:
00151                 ns_obj._init_cam_info()
00152             except:
00153                 print >> sys.stderr, "%s does not appear to be a camera topic"%ns_obj._name
00154                 return None
00155             
00156     # image_view doesn't die when the user closes the window, use py_image_view or rviz instead.
00157     # execute in subprocess to keep wx out of this VM
00158 
00159     #TODO: convert to Node
00160     #TODO: pass in height/width from cam info into py_image_view for default window size
00161     d = roslib.packages.get_pkg_dir(PKG)
00162     mod = os.path.join(d, 'src', PKG, 'py_image_view.py')
00163     cmd = ['python', mod, '-t', roslib.names.ns_join(ns_obj._name, 'image_raw')]
00164     rosh.impl.proc.run(ns_obj._config, cmd)
00165     print "running py_image_viewer, this may be slow over a wireless network"
00166     return True


rosh_common
Author(s): Ken Conley
autogenerated on Mon Dec 2 2013 13:19:01