move.py
Go to the documentation of this file.
00001 
00002 
00003 #!/usr/bin/env python
00004 
00005 """Base code provided by I Heart Robotics, modified extensivly by Peter Tran. It now
00006 includes a sentry function that allows the robot to survey its surroundings for
00007 persons, as well as giving the robot a new direction to travel in. The code now also
00008 includes a bumper sensor, to avoid the robot from running into things it does not detect
00009 with kinect data. The code is also intergrated with tracking.py and follow.py so that
00010 if it detects a person, it will stop moving autonomously and begin following."""
00011 
00012 import rospy
00013 import tf
00014 from geometry_msgs.msg import Twist
00015 from sensor_msgs.msg import LaserScan
00016 from std_msgs.msg import Bool
00017 from kobuki_msgs.msg import BumperEvent, CliffEvent
00018 from random import randint
00019 
00020 class Scan_msg:
00021 
00022         def __init__(self):
00023                 '''Initializes an object of this class.
00024 
00025                 The constructor creates a publisher, a twist message.
00026                 3 integer variables are created to keep track of where obstacles exist.
00027                 3 dictionaries are to keep track of the movement and log messages.'''
00028                 self.bump_subscriber = rospy.Subscriber('/mobile_base/events/bumper', BumperEvent, self.bumper_event_callback)
00029                 self.wheel_drop_subscriber = rospy.Subscriber('/mobile_base/events/wheel_drop', CliffEvent, self.cliff_event_callback)
00030                 self.pub = rospy.Publisher('/cmd_vel_mux/input/navi',Twist,queue_size = 10)
00031                 self.msg = Twist()
00032                 self.sect_1 = 0
00033                 self.sect_2 = 0
00034                 self.sect_3 = 0
00035                 """self.ang and self.fwd is used to determine how the robot will move according to
00036                 its position relative to the sensors"""
00037                 self.ang = {0:0,001:-1.2,10:-1.2,11:-1.2,100:1.5,101:1.0,110:1.0,111:1.2}
00038                 self.fwd = {0:.2,1:0,10:0,11:0,100:0.1,101:0,110:0,111:0}
00039                 self.dbgmsg = {0:'Move forward',1:'Veer right',10:'Veer right',11:'Veer right',100:'Veer left',101:'Veer left',110:'Veer left',111:'Veer right'}
00040 
00041         def reset_sect(self):
00042                 '''Resets the below variables before each new scan message is read'''
00043                 self.sect_1 = 0
00044                 self.sect_2 = 0
00045                 self.sect_3 = 0
00046 
00047         def sort(self, laserscan):
00048                 '''Goes through 'ranges' array in laserscan message and determines 
00049                 where obstacles are located. The class variables sect_1, sect_2, 
00050                 and sect_3 are updated as either '0' (no obstacles within 0.7 m)
00051                 or '1' (obstacles within 0.7 m)
00052 
00053                 Parameter laserscan is a laserscan message.'''
00054                 entries = len(laserscan.ranges)
00055                 for entry in range(0,entries):
00056                         if 0.01 < laserscan.ranges[entry] < 0.75:
00057                                 self.sect_1 = 1 if (0 < entry < entries/3) else 0 
00058                                 self.sect_2 = 1 if (entries/3 < entry < entries/2) else 0
00059                                 self.sect_3 = 1 if (entries/2 < entry < entries) else 0
00060                 #rospy.loginfo("sort complete,sect_1: " + str(self.sect_1) + " sect_2: " + str(self.sect_2) + " sect_3: " + str(self.sect_3))
00061 
00062         def movement(self, sect1, sect2, sect3):
00063                 '''Uses the information known about the obstacles to move robot.
00064 
00065                 Parameters are class variables and are used to assign a value to
00066                 variable sect and then  set the appropriate angular and linear 
00067                 velocities, and log messages.
00068                 These are published and the sect variables are reset.'''
00069                 sect = int(str(self.sect_1) + str(self.sect_2) + str(self.sect_3))
00070                 #rospy.loginfo("Sect = " + str(sect))
00071 
00072                 """This is where the sentry function comes in, the robot will randomly, at a low
00073                 chance, spin around in a circle for a random amount of time surveying the environment
00074                 as well as randomizing which direction it will be facing."""
00075                 i = randint(0,2000)
00076                 if i > 1998:
00077                         crosscounter = randint(10000,100000)
00078                         j = 0
00079                         i = 0
00080                         for j in range(0, crosscounter):
00081                                 self.msg.angular.z = .5
00082                                 self.msg.linear.x = 0
00083                                 self.pub.publish(self.msg)
00084                                 j = j + 1
00085                 i = 0
00086 
00087                 self.msg.angular.z = self.ang[sect]
00088                 self.msg.linear.x = self.fwd[sect]
00089                 #rospy.loginfo(self.dbgmsg[sect])
00090                 self.pub.publish(self.msg)
00091 
00092                 self.reset_sect()
00093 
00094         def bumper_event_callback(self, msg):
00095                 """Checks to see if the bumper has been pressed, if so the robot will then
00096                 back up and turn in a random direction."""
00097                 k = 0
00098                 if msg.state == BumperEvent.PRESSED:    
00099                         for k in range(0, 4999):
00100                                 self.msg.angular.z = 0
00101                                 self.msg.linear.x = -0.1
00102                                 self.pub.publish(self.msg)
00103                                 k = k + 1
00104 
00105                         k = 0
00106                         crosscounter = randint(5000,50000)
00107                         orientation = randint(-1,1)
00108                         for orientation in range (0, 0):
00109                                 orientation = randint(-1,1)
00110 
00111                         for k in range(0, crosscounter):
00112                                 self.msg.angular.z = orientation
00113                                 self.msg.linear.x = 0
00114                                 self.pub.publish(self.msg)
00115                                 k = k + 1
00116 
00117         def cliff_event_callback(self, msg):
00118                 """Checks to see if the robot is over a cliff. If so, then backs up to turn in
00119                 a random direction. Currently does not work, be careful not to trash your
00120                 robot."""
00121                 k = 0
00122                 if msg.state == CliffEvent.CLIFF:
00123                         for k in range(0, 4999):
00124                                 self.msg.angular.z = 0
00125                                 self.msg.linear.x = -0.1
00126                                 self.pub.publish(self.msg)
00127                                 k = k + 1
00128 
00129                         k = 0
00130                         crosscounter = randint(5000,50000)
00131                         orientation = randint(-1,1)
00132                         for orientation in range (0, 0):
00133                                 orientation = randint(-1,1)
00134 
00135                         for k in range(0, crosscounter):
00136                                 self.msg.angular.z = orientation
00137                                 self.msg.linear.x = 0
00138                                 self.pub.publish(self.msg)
00139                                 k = k + 1
00140 
00141         def move_callback(self, data):
00142                 """Checks to see if the subscriber from tracking.py is sending in a value
00143                 of False before sending movement commands to the robot. This is to avoid
00144                 the robot from both trying to follow a person as well as autonomously
00145                 navigate."""
00146                 while str(data) == "data: False":
00147                         self.movement(self.sect_1, self.sect_2, self.sect_3)
00148 
00149         def for_callback(self, laserscan):
00150                 '''Passes laserscan onto function sort which gives the sect 
00151                 variables the proper values.  Then the movement function is run 
00152                 with the class sect variables as parameters.
00153 
00154                 Parameter laserscan is received from callback function.
00155 
00156                 Also subscribes to tracking.py.'''
00157                 self.sort(laserscan)
00158                 self.sub = rospy.Subscriber("move", Bool, self.move_callback)
00159                 #self.movement(self.sect_1, self.sect_2, self.sect_3)
00160 
00161 def call_back(scanmsg):
00162         '''Passes laser scan message to for_callback function of sub_obj.
00163 
00164         Parameter scanmsg is laserscan message.'''
00165         sub_obj.for_callback(scanmsg)
00166 
00167 def listener():
00168         '''Initializes node, creates subscriber, and states callback 
00169         function.'''
00170         rospy.init_node('navigation_sensors')
00171         rospy.loginfo("Subscriber Starting")
00172         tracker_subscriber = rospy.Subscriber("tracking", Bool, tracker_callback)
00173         sub = rospy.Subscriber('/scan', LaserScan, call_back)
00174         rospy.spin()
00175 
00176 def tracker_callback(data):
00177         """Checks to see if the subscriber from tracking.py has sent in a True value for
00178         tracking a person. If True, it will publish to follow.py to begin following."""
00179         if str(data) == "data: True":
00180                 pub = rospy.Publisher('move', Bool,queue_size=10)
00181                 pub.publish(True)
00182 
00183 if __name__ == "__main__":
00184         '''A Scan_msg class object called sub_obj is created and listener
00185         function is run''' 
00186         sub_obj = Scan_msg()
00187         listener()
00188 


gapter
Author(s):
autogenerated on Thu Jun 6 2019 22:05:13