segmented_arc_base_controller.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 """
00004 listen to /move_base/TrajectoryPlannerROS/local_plan
00005 use rotate and movedistance commands to get there, repeat
00006 subscribe to odo so moves relative to current pos
00007 assumes robot is stopped before running this
00008 
00009 rosmsg show nav_msgs/Path
00010 rosmsg show nav_msgs/Odometry
00011 rosmsg show geometry_msgs/PoseStamped << is in map frame!!!
00012 
00013 consider polling telnet and broadcasting odom from here, to only update odom between moves
00014 /move_base/status  3 = goal reached, 1= accepted (read last in list)
00015 rosmsg show actionlib_msgs/GoalStatusArray
00016 
00017 adding initial pose to goal pose:
00018 1st test, initial poseth -90deg: solution would be just ot add initial pose to goal pose
00019         gth = gth + ith
00020         180 = 180 + (-90)
00021         if dth > math.pi:
00022                 dth = -math.pi*2 + dth
00023         elif dth < -math.pi:
00024                 dth = math.pi*2 + dth
00025 ^^ works but not if odom gets whacked - need to use odom/map tf and ADD to goal pose diff
00026 """
00027 
00028 import rospy, tf
00029 import oculusprimesocket
00030 from nav_msgs.msg import Odometry
00031 import math
00032 from nav_msgs.msg import Path
00033 from geometry_msgs.msg import PoseStamped #, PoseWithCovarianceStamped
00034 from actionlib_msgs.msg import GoalStatusArray
00035 
00036 listentime = 1.5 # constant, seconds
00037 nextmove = 0
00038 odomx = 0
00039 odomy = 0
00040 odomth = 0
00041 targetx = 0
00042 targety = 0
00043 targetth = 0
00044 followpath = False
00045 goalth = 0 
00046 minturn = math.radians(6) # 0.21 minimum for pwm 255
00047 lastpath = 0
00048 goalpose = False
00049 goalseek = False
00050 linearspeed = 150
00051 secondspermeter = 3.2 #float
00052 turnspeed = 100
00053 secondspertwopi = 3.8
00054 initth = 0
00055 #initgoalth = 0
00056 tfth = 0
00057 
00058 def pathCallback(data):
00059         global targetx, targety, targetth, followpath, lastpath, goalpose
00060         lastpath = rospy.get_time()
00061         goalpose = False
00062         followpath = True
00063         p = data.poses[len(data.poses)-1] # get latest pose
00064         targetx = p.pose.position.x
00065         targety = p.pose.position.y
00066         quaternion = ( p.pose.orientation.x, p.pose.orientation.y,
00067         p.pose.orientation.z, p.pose.orientation.w )
00068         targetth = tf.transformations.euler_from_quaternion(quaternion)[2]
00069 
00070 def odomCallback(data):
00071         global odomx, odomy, odomth
00072         odomx = data.pose.pose.position.x
00073         odomy = data.pose.pose.position.y
00074         quaternion = ( data.pose.pose.orientation.x, data.pose.pose.orientation.y,
00075         data.pose.pose.orientation.z, data.pose.pose.orientation.w )
00076         odomth = tf.transformations.euler_from_quaternion(quaternion)[2]
00077         
00078 def goalCallback(data):
00079         global goalth, followpath, lastpath, goalpose, odomx, odomy, odomth, targetx, targety, targetth
00080         goalpose = False
00081         followpath = True
00082         lastpath = 0
00083         targetx = odomx
00084         targety = odomy
00085         
00086         if goalpose:
00087                 targetth = goalth # - tfth
00088         else:
00089                 targetth = odomth  # + tfth      
00090                 
00091         # if targetth > math.pi:
00092                 # targetth = -math.pi*2 + targetth
00093         # elif targetth < -math.pi:
00094                 # targetth = math.pi*2 + targetth
00095                 
00096         quaternion = ( data.pose.orientation.x, data.pose.orientation.y,
00097         data.pose.orientation.z, data.pose.orientation.w )
00098         goalth = tf.transformations.euler_from_quaternion(quaternion)[2]
00099         # goalth -= tfth
00100         # if goalth > math.pi:
00101                 # goalth = -math.pi*2 + goalth
00102         # elif goalth < -math.pi:
00103                 # goalth = math.pi*2 + goalth
00104         
00105 def goalStatusCallback(data):
00106         global goalseek
00107         goalseek = False
00108         if len(data.status_list) == 0:
00109                 return
00110         status = data.status_list[len(data.status_list)-1] # get latest status
00111         if status.status == 1:
00112                 goalseek = True
00113                 
00114 # def initialposeCallback(data):
00115         # global initth
00116         # quaternion = ( data.pose.pose.orientation.x, data.pose.pose.orientation.y,
00117         # data.pose.pose.orientation.z, data.pose.pose.orientation.w )
00118         # initth = tf.transformations.euler_from_quaternion(quaternion)[2]
00119 
00120 # def amclposeCallback(data):
00121         # global goalth, initgoalth
00122         # quaternion = ( data.pose.pose.orientation.x, data.pose.pose.orientation.y,
00123         # data.pose.pose.orientation.z, data.pose.pose.orientation.w )
00124         # amclth = tf.transformations.euler_from_quaternion(quaternion)[2]
00125         # goalth = initgoalth - amclth
00126         # if goalth > math.pi:
00127                 # goalth = -math.pi*2 + goalth
00128         # elif goalth < -math.pi:
00129                 # goalth = math.pi*2 + goalth
00130 
00131 def move(ox, oy, oth, tx, ty, tth, gth):
00132         global followpath, goalpose, tfth
00133 
00134         # print "odom: "+str(ox)+", "+str(oy)+", "+str(oth)
00135         # print "target: "+str(tx)+", "+str(ty)+", "+str(tth)
00136         
00137         distance = 0
00138         if followpath:
00139                 dx = tx - ox
00140                 dy = ty - oy    
00141                 distance = math.sqrt( pow(dx,2) + pow(dy,2) )
00142         
00143         if distance > 0:
00144                 th = math.acos(dx/distance)
00145                 if dy <0:
00146                         th = -th
00147         elif goalpose:
00148                 th = gth - tfth
00149         else:
00150                 th = tth
00151 
00152         #if goalpose:
00153                 #th = gth
00154                 #distance = 0
00155         
00156         dth = th - oth
00157         if dth > math.pi:
00158                 dth = -math.pi*2 + dth
00159         elif dth < -math.pi:
00160                 dth = math.pi*2 + dth
00161                 
00162         # force minimums        
00163         if distance > 0 and distance < 0.05:
00164                 distance = 0.05
00165 
00166         # supposed to reduce zig zagging
00167         if dth < minturn*0.3 and dth > -minturn*0.3:
00168                 dth = 0
00169         elif dth >= minturn*0.3 and dth < minturn:
00170                 dth = minturn
00171         elif dth <= -minturn*0.3 and dth > -minturn:
00172                 dth = -minturn
00173 
00174 
00175         if dth > 0:
00176                 oculusprimesocket.sendString("speed "+str(turnspeed) )
00177                 oculusprimesocket.sendString("move left")
00178                 rospy.sleep(dth/(2.0*math.pi) * secondspertwopi)
00179                 oculusprimesocket.sendString("move stop")
00180                 oculusprimesocket.waitForReplySearch("<state> direction stop")
00181         elif dth < 0:
00182                 oculusprimesocket.sendString("speed "+str(turnspeed) )
00183                 oculusprimesocket.sendString("move right")
00184                 rospy.sleep(-dth/(2.0*math.pi) * secondspertwopi)
00185                 oculusprimesocket.sendString("move stop")
00186                 oculusprimesocket.waitForReplySearch("<state> direction stop")
00187 
00188         if distance > 0:
00189                 oculusprimesocket.sendString("speed "+str(linearspeed) )
00190                 oculusprimesocket.sendString("move forward")
00191                 rospy.sleep(distance*secondspermeter)
00192                 oculusprimesocket.sendString("move stop")
00193                 oculusprimesocket.waitForReplySearch("<state> direction stop")
00194         
00195 def cleanup():
00196         oculusprimesocket.sendString("odometrystop")
00197         oculusprimesocket.sendString("state stopbetweenmoves false")
00198         oculusprimesocket.sendString("move stop")
00199 
00200 
00201 # MAIN
00202 
00203 rospy.init_node('base_controller', anonymous=False)
00204 rospy.Subscriber("move_base/TrajectoryPlannerROS/local_plan", Path, pathCallback)
00205 rospy.Subscriber("odom", Odometry, odomCallback)
00206 rospy.Subscriber("move_base_simple/goal", PoseStamped, goalCallback)
00207 rospy.Subscriber("move_base/status", GoalStatusArray, goalStatusCallback)
00208 # rospy.Subscriber("initialpose", PoseWithCovarianceStamped, initialposeCallback)
00209 # rospy.Subscriber("amcl_pose", PoseWithCovarianceStamped, amclposeCallback)
00210 rospy.on_shutdown(cleanup)
00211 listener = tf.TransformListener()
00212 
00213 while not rospy.is_shutdown():
00214         t = rospy.get_time()
00215         
00216         if t >= nextmove and goalseek:
00217                 move(odomx, odomy, odomth, targetx, targety, targetth, goalth)
00218                 nextmove = t + listentime
00219                 # nextmove = rospy.get_time()+listentime
00220                 followpath = False
00221         
00222         if t - lastpath > 3:
00223                 goalpose = True
00224         
00225         try:
00226                 (trans,rot) = listener.lookupTransform('/map', '/odom', rospy.Time(0))
00227         except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException):
00228                 continue                
00229         quaternion = (rot[0], rot[1], rot[2], rot[3])
00230         tfth = tf.transformations.euler_from_quaternion(quaternion)[2]
00231                 
00232 cleanup()


oculusprime
Author(s): Colin Adamson
autogenerated on Sat Jun 8 2019 20:04:29