Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 import rospy
00010 import math
00011 import std_msgs.msg as std_msgs
00012 import geometry_msgs.msg as geometry_msgs
00013
00014
00015
00016
00017
00018
00019
00020 class Rotate(object):
00021 '''
00022 implements a rotating motion.
00023 '''
00024 __slots__ = [
00025 'yaw_absolute_rate',
00026 'yaw_direction',
00027 '_stop',
00028 '_cmd_vel_topic',
00029 '_cmd_vel_publisher',
00030 '_cmd_vel_frequency',
00031 '_rate',
00032 '_running',
00033 '_twist',
00034 '_listener',
00035 '_initialise_pose_trigger'
00036 ]
00037 CLOCKWISE = -1
00038 COUNTER_CLOCKWISE = 1
00039
00040 def __init__(self, cmd_vel_topic):
00041 self._cmd_vel_publisher = None
00042 self._cmd_vel_frequency = 5
00043 self._cmd_vel_topic = cmd_vel_topic
00044 self._rate = rospy.Rate(self._cmd_vel_frequency)
00045 self._stop = False
00046 self._running = False
00047 self._initialise_pose_trigger = rospy.Publisher('~initialise', std_msgs.Empty, queue_size=5)
00048
00049 twist = geometry_msgs.Twist()
00050 twist.linear.x = 0
00051 twist.linear.y = 0
00052 twist.linear.z = 0
00053 twist.angular.x = 0
00054 twist.angular.y = 0
00055 twist.angular.z = 0
00056 self._twist = twist
00057
00058 self.init()
00059
00060 def init(self, yaw_absolute_rate=1.2, yaw_direction=CLOCKWISE):
00061 '''
00062 Initialise the direction and rate the robot should rotate at.
00063 '''
00064 self.yaw_absolute_rate = yaw_absolute_rate
00065 self.yaw_direction = yaw_direction
00066
00067 def shutdown(self):
00068 self.stop()
00069 while self._running:
00070 rospy.sleep(0.01)
00071
00072 def is_running(self):
00073 return self._running
00074
00075 def change_direction(self):
00076 if self.yaw_direction == Rotate.CLOCKWISE:
00077 self.yaw_direction = Rotate.COUNTER_CLOCKWISE
00078 else:
00079 self.yaw_direction = Rotate.CLOCKWISE
00080
00081 def is_stopped(self):
00082 return self._stop
00083
00084 def stop(self):
00085 self._stop = True
00086
00087 def execute(self):
00088 '''
00089 Drop this into threading.Thread or QThread for execution
00090 '''
00091 if self._running:
00092 rospy.logerr("AR Pair Search: already executing a motion, ignoring the request")
00093 return
00094 self._cmd_vel_publisher = rospy.Publisher(self._cmd_vel_topic, geometry_msgs.Twist, queue_size=10)
00095 self._stop = False
00096 self._running = True
00097 start = rospy.get_rostime()
00098 rospy.sleep(0.3)
00099 result = False
00100 twist = self._twist
00101 while not self._stop and not rospy.is_shutdown():
00102 update = self.yaw_direction * self.yaw_absolute_rate / 10.0
00103 if math.fabs(twist.angular.z) < self.yaw_absolute_rate:
00104 twist.angular.z = twist.angular.z + update
00105 else:
00106
00107 twist.angular.z = self.yaw_direction * self.yaw_absolute_rate
00108 now = rospy.get_rostime()
00109 rospy.logdebug("AR Pair Search: rotate: %s rad/s [%ss]" % (twist.angular.z, str(now.secs - start.secs)))
00110 try:
00111 self._cmd_vel_publisher.publish(twist)
00112 except rospy.ROSException:
00113 break
00114 self._rate.sleep()
00115 if not rospy.is_shutdown():
00116 cmd = geometry_msgs.Twist()
00117 cmd.angular.z = 0.0
00118 self._cmd_vel_publisher.publish(cmd)
00119 self._initialise_pose_trigger.publish(std_msgs.Empty())
00120 result = True
00121 self._cmd_vel_publisher.unregister()
00122 self._cmd_vel_publisher = None
00123 self._running = False
00124 return result