$search
00001 #!/usr/bin/env python 00002 00003 """ 00004 base_scan.py - A panning sonar sensor used to get a pretend "laser scan" for ROS SLAM 00005 Created for the Pi Robot Project: http://www.pirobot.org 00006 Copyright (c) 2010 Patrick Goebel. All rights reserved. 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 2 of the License, or 00011 (at your option) any later version. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details at: 00017 00018 http://www.gnu.org/licenses/gpl.html 00019 00020 NOTE: This code borrows heavily from Michael Ferguson's Poor Man's Lidar code. 00021 """ 00022 00023 import roslib; roslib.load_manifest('pi_robot') 00024 import rospy 00025 from sensor_msgs.msg import LaserScan 00026 from tf.broadcaster import TransformBroadcaster 00027 from serializer.srv import * 00028 from serializer.msg import * 00029 from math import pi, pow 00030 import time 00031 from threading import Thread, Event 00032 00033 class base_scan(Thread): 00034 def __init__(self, Serializer, name): 00035 Thread.__init__ (self) 00036 self.finished = Event() 00037 #rospy.init_node("base_scan") 00038 self.Serializer = Serializer 00039 self.scanPub = rospy.Publisher('/base_scan', LaserScan) 00040 #self.scanBroadcaster = TransformBroadcaster() 00041 #rospy.Subscriber("sensors", SensorState, self.sensorCallback) 00042 00043 self.rate = 1 00044 rospy.loginfo("Started base scan at " + str(self.rate) + " Hz") 00045 00046 self.sonar = 0.128 00047 00048 # Scanning servo 00049 self.servo_id = 2 00050 self.sonar_id = 5 00051 self.ir_id = 3 00052 self.right = 60 00053 self.left = -80 00054 # self.right = 70 00055 # self.left = -90 00056 self.sweep_angle = pi * (self.right - self.left) / 200. 00057 self.angle_max = self.sweep_angle / 2.0 00058 self.angle_min = -self.angle_max 00059 self.n_samples = 15 00060 self.angle_increment = self.sweep_angle / self.n_samples 00061 self.servo_increment = (self.right - self.left) / self.n_samples 00062 self.range_min = 0.2 00063 self.range_max = 5.0 00064 00065 self.setServo(self.servo_id, (self.right - self.left) / 2 + self.left) 00066 #self.Serializer.servo(self.servo_id, self.right) 00067 self.servo_direction = 1 00068 self.count = 0 00069 00070 # sonar = None 00071 # while sonar == None: 00072 # sonar = self.getPing(self.sensor_id, False) 00073 # rospy.loginfo("Initial Sonar Reading: " + str(sonar)) 00074 00075 ir = None 00076 while ir == None: 00077 rospy.loginfo("Getting IR Reading: " + str(ir)) 00078 ir = self.SharpGP2Y0A0(self.Serializer.sensor(self.ir_id)) 00079 rospy.loginfo("Initial IR Reading: " + str(ir)) 00080 00081 def run(self): 00082 rosRate = rospy.Rate(self.rate) 00083 rospy.loginfo("Executing base scan at: " + str(self.rate) + " Hz") 00084 00085 while not rospy.is_shutdown(): 00086 00087 ranges = list() 00088 00089 if self.servo_direction > 0: 00090 #self.Serializer.servo(self.servo_id, self.left + i * self.servo_increment) 00091 self.Serializer.servo(self.servo_id, self.left) 00092 else: 00093 #self.Serializer.servo(self.servo_id, self.right - i * self.servo_increment) 00094 self.Serializer.servo(self.servo_id, self.right) 00095 00096 #time.sleep(0.05) 00097 00098 for i in range(self.n_samples): 00099 #sonar = self.getPing(self.sensor_id, False) 00100 start = time.time() 00101 ir = self.SharpGP2Y0A0(self.Serializer.sensor(self.ir_id)) 00102 ranges.append(ir / 100.0) 00103 delta = time.time() - start 00104 #rospy.loginfo("Delta" + str(delta)) 00105 time.sleep(max(0, 0.05 - delta)) 00106 00107 #time.sleep(0.03) 00108 00109 # 00110 # for i in range(self.n_samples): 00111 # #sonar = self.getPing(self.sensor_id, False) 00112 # ir = self.SharpGP2Y0A0(self.getAnalog(self.ir_id)) 00113 # ranges.append(ir / 100.0) 00114 # #rospy.loginfo("IR: " + str(ir)) 00115 # #time.sleep(0.03333) 00116 00117 if self.servo_direction < 0: 00118 ranges.reverse() 00119 00120 scan = LaserScan() 00121 scan.header.stamp = rospy.Time.now() 00122 scan.header.frame_id = "/base_laser" 00123 scan.angle_min = self.angle_min 00124 scan.angle_max = self.angle_max 00125 scan.angle_increment = self.angle_increment 00126 scan.scan_time = self.rate 00127 scan.range_min = self.range_min 00128 scan.range_max = self.range_max 00129 scan.ranges = ranges 00130 self.scanPub.publish(scan) 00131 00132 self.servo_direction *= -1 00133 00134 # scan = LaserScan() 00135 # scan.header.stamp = rospy.Time.now() 00136 # scan.header.frame_id = "base_link" 00137 # scan.angle_min = -1.57 00138 # scan.angle_max = 1.57 00139 # scan.angle_increment = 0.108275862 00140 # scan.scan_time = 1.0 / self.rate 00141 # scan.range_min = 0.5 00142 # scan.range_max = 6.0 00143 # scan.ranges = ranges 00144 # scanPub.publish(scan) 00145 00146 rosRate.sleep() 00147 00148 def stop(self): 00149 print "Shutting down base scan" 00150 self.finished.set() 00151 self.join() 00152 00153 def setServo(self, id, position): 00154 rospy.wait_for_service('SetServo') 00155 try: 00156 servoProxy = rospy.ServiceProxy('SetServo', SetServo) 00157 return servoProxy(id, position) 00158 except rospy.ServiceException, e: 00159 print "Service call failed: %s"%e 00160 00161 def getPing(self, id, cached): 00162 rospy.wait_for_service('Ping') 00163 try: 00164 pingProxy = rospy.ServiceProxy('Ping', Ping) 00165 response = pingProxy(id, cached) 00166 return response.value 00167 except rospy.ServiceException, e: 00168 print "Service call failed: %s"%e 00169 00170 def getVoltage(self, cached): 00171 rospy.wait_for_service('Voltage') 00172 try: 00173 voltageProxy = rospy.ServiceProxy('Voltage', Voltage) 00174 response = voltageProxy(cached) 00175 voltage = response.value 00176 return voltage 00177 except rospy.ServiceException, e: 00178 print "Service call failed: %s"%e 00179 00180 def getAnalog(self, id): 00181 rospy.wait_for_service('GetAnalog') 00182 try: 00183 analogProxy = rospy.ServiceProxy('GetAnalog', GetAnalog) 00184 response = analogProxy(id) 00185 return response.value 00186 except rospy.ServiceException, e: 00187 print "Service call failed: %s"%e 00188 00189 def sensorCallback(self, data): 00190 self.sonar = data.value[0] / 100. 00191 #rospy.loginfo("Sensor Data: " + str(data.value)) 00192 00193 def SharpGP2Y0A0(self, reading): 00194 if reading <= 90: 00195 range = 500 # Max range is actually 150 cm 00196 else: 00197 try: 00198 range = (11341 / (reading - 17.562)) - 3 00199 except: 00200 range = 150 00201 return range 00202 00203 00204 if __name__ == '__main__': 00205 try: 00206 myBaseScan = base_scan() 00207 myBaseScan.start() 00208 except rospy.ROSInterruptException: 00209 pass