base_scan.py
Go to the documentation of this file.
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


serializer
Author(s): Patrick Goebel
autogenerated on Mon Oct 6 2014 12:12:01