camera_listener.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #
00003 # Software License Agreement (BSD License)
00004 #
00005 # Copyright (c) 2008, Willow Garage, Inc.
00006 # All rights reserved.
00007 #
00008 # Redistribution and use in source and binary forms, with or without
00009 # modification, are permitted provided that the following conditions
00010 # are met:
00011 #
00012 #  * Redistributions of source code must retain the above copyright
00013 #    notice, this list of conditions and the following disclaimer.
00014 #  * Redistributions in binary form must reproduce the above
00015 #    copyright notice, this list of conditions and the following
00016 #    disclaimer in the documentation and/or other materials provided
00017 #    with the distribution.
00018 #  * Neither the name of Willow Garage, Inc. nor the names of its
00019 #    contributors may be used to endorse or promote products derived
00020 #    from this software without specific prior written permission.
00021 #
00022 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033 # POSSIBILITY OF SUCH DAMAGE.
00034 #
00035 
00036 ##\author Kevin Watts
00037 ##\brief Listens to diagnostics from wge100 camera and reports OK/FAIL
00038 
00039 
00040 from __future__ import with_statement
00041 
00042 PKG = 'pr2_hardware_test_monitor'
00043 import roslib; roslib.load_manifest(PKG)
00044 
00045 from diagnostic_msgs.msg import DiagnosticArray, DiagnosticStatus, KeyValue
00046 from std_srvs.srv import *
00047 
00048 import rospy
00049 
00050 import threading
00051 
00052 from pr2_hw_listener import PR2HWListenerBase
00053 
00054 STALE_TIMEOUT = 8.0
00055 ERROR_TIMEOUT = 8.0
00056 ERROR_MAX = 3
00057 
00058 class CameraListener(PR2HWListenerBase):
00059     def __init__(self):
00060         self._diag_sub = rospy.Subscriber('/diagnostics', DiagnosticArray, self._diag_callback)
00061         self._mutex = threading.Lock()
00062 
00063         self._lvl = 3 # No updates
00064         self._update_time = 0
00065 
00066         # Record last good message and the time
00067         self._last_ok_time = rospy.get_time()
00068         self._error_cnt = 0 # Increment on error, reset on OK. Leave value on warning
00069         self._last_msg_ok = False # True if last value was OK
00070 
00071         self._was_stale = True # Warn if we go stale
00072         self._reported_vals = False # Log whether we've reported any errors
00073 
00074     def _diag_callback(self, msg):
00075         with self._mutex:
00076             has_wge100 = False
00077             this_lvl = 0
00078             this_msg = ''
00079             for stat in msg.status:
00080                 if stat.name.find('wge100') >= 0:
00081                     this_lvl = max(stat.level, this_lvl)
00082                     self._update_time = rospy.get_time()
00083                     has_wge100 = True
00084                     
00085                     if stat.level == this_lvl:
00086                         this_msg = stat.message
00087 
00088             if has_wge100:
00089                 if this_lvl == 0:
00090                     self._last_ok_time = rospy.get_time()
00091                     self._error_cnt = 0
00092 
00093                     # Don't reset last_msg value until we're reported it
00094                     if self._reported_vals:
00095                         self._last_msg_ok = True
00096                 else:
00097                     self._last_msg_ok = False
00098 
00099                 if this_lvl > 1: # Received error value
00100                     rospy.logwarn('Camera error from wge100 camera. Message: %s' % this_msg)
00101                     self._error_cnt += 1
00102 
00103                 self._was_stale = False
00104                 self._reported_vals = False
00105 
00106     
00107     def check_ok(self):
00108         with self._mutex:
00109             msg = 'OK'
00110             lvl = 0 
00111 
00112             # Report a warning if we saw a warning or error in last message
00113             if not self._last_msg_ok:
00114                 lvl = 1
00115                 msg = 'Camera Warning'
00116 
00117             # Report error if we've seen multiple errors, or gone too long without good message
00118             if self._error_cnt > ERROR_MAX or rospy.get_time() - self._last_ok_time > ERROR_TIMEOUT:
00119                 lvl = 2
00120                 msg = 'Camera Error'
00121                 if rospy.get_time() - self._last_ok_time > ERROR_TIMEOUT:
00122                     rospy.logwarn('Too long since last OK message received. Camera error')
00123 
00124             if rospy.get_time() - self._update_time > STALE_TIMEOUT:
00125                 if not self._was_stale:
00126                     rospy.logerr('wge100 camera is stale. No updates from camera')
00127                 self._was_stale = True
00128 
00129                 lvl = 3
00130                 msg = 'Camera Stale'
00131                 if self._update_time == 0:
00132                     msg = 'No Camera Data'
00133         
00134             # We've reported everything, so we can reset ourselves
00135             self._reported_vals = True
00136 
00137         return lvl, msg, None
00138     


pr2_hardware_test_monitor
Author(s): Kevin Watts
autogenerated on Sat Dec 28 2013 17:54:19