00001
00002 import math
00003 import roslib; roslib.load_manifest('teer_example_turtle')
00004 import rospy
00005 import numpy as np
00006 from turtlesim.msg import Velocity
00007 from turtlesim.msg import Pose
00008 from turtlesim.srv import TeleportAbsolute
00009 from turtlesim.srv import SetPen
00010 from turtlesim.srv import Spawn
00011 from std_srvs.srv import Empty as EmptyServiceCall
00012 from turtle_math import *
00013 from teer_ros import *
00014
00015 class TurtleScheduler(Scheduler):
00016 """ A teer scheduler working with ROS """
00017
00018 turtle1_pose = ConditionVariable(None)
00019 turtle2_pose = ConditionVariable(None)
00020
00021 def __init__(self):
00022 """ Init the ROS scheduler """
00023 super(TurtleScheduler,self).__init__()
00024
00025 def turtle1_go(target):
00026 """ Make turtle1 go to target, giving new speed command every 0.2 s """
00027 while True:
00028
00029 turtle1_velocity.publish(control_command(sched.turtle1_pose, target, 1.0))
00030
00031 yield WaitDuration(0.2)
00032
00033 def turtle1_align(target_angle):
00034 """ Make turtle1 align to angle, giving new speed command every second """
00035 diff = angle_diff(sched.turtle1_pose.theta, target_angle)
00036 sign_diff = math.copysign(1, diff)
00037 while True:
00038
00039 turtle1_velocity.publish(Velocity(0,-sign_diff))
00040
00041 yield WaitDuration(1)
00042
00043 def turtle2_orbit(target):
00044 """ Make turtle2 orbit around target, giving new speed command every second """
00045 while True:
00046
00047 turtle2_velocity.publish(orbit_command(sched.turtle2_pose, target, 1.0))
00048
00049 yield WaitDuration(0.2)
00050
00051 def turtle1_coverage():
00052 """ Make turtle1 do a square in the environment """
00053 yield WaitCondition(lambda: sched.turtle1_pose is not None)
00054 try:
00055 l = round(sched.turtle1_pose.y/2.)*2
00056 if l > 8:
00057 l = 2
00058 sched.printd('Restarting at ' + str(l))
00059 while True:
00060 targets = [(2,l), (8,l), (9,l+0.5), (8,l+1), (2,l+1), (1,l+1.5)]
00061 for target in targets:
00062 go_tid = sched.new_task(turtle1_go(target))
00063 yield WaitCondition(lambda: dist(sched.turtle1_pose, target) < 0.1)
00064 sched.kill_task(go_tid)
00065 l += 2
00066 if l > 8:
00067 l = 2
00068 except GeneratorExit:
00069 sched.kill_task(go_tid)
00070 raise
00071
00072 def turtle2_orbiting():
00073 """ Make turtle2 do a square in the environment, reverse direction as turtle1 """
00074 yield WaitCondition(lambda: sched.turtle2_pose is not None)
00075 coverage_tid = sched.new_task(turtle1_coverage())
00076 orbit_tid = sched.new_task(turtle2_orbit((5, 5.5)))
00077 while True:
00078 yield WaitCondition(lambda: dist(sched.turtle1_pose, sched.turtle2_pose) < 1)
00079 sched.printd('Met friend, exchange data')
00080 sched.pause_task(orbit_tid)
00081 turtle2_velocity.publish(Velocity(0,0))
00082 sched.kill_task(coverage_tid)
00083 if sched.turtle1_pose.y < 5.5:
00084 align_tid = sched.new_task(turtle1_align(math.pi/2))
00085 yield WaitCondition(lambda: abs(angle_diff(sched.turtle1_pose.theta, math.pi/2)) < 0.1)
00086 sched.kill_task(align_tid)
00087 target = (sched.turtle1_pose.x, sched.turtle1_pose.y + 3)
00088 else:
00089 align_tid = sched.new_task(turtle1_align(-math.pi/2))
00090 yield WaitCondition(lambda: abs(angle_diff(sched.turtle1_pose.theta, -math.pi/2)) < 0.1)
00091 sched.kill_task(align_tid)
00092 target = (sched.turtle1_pose.x, sched.turtle1_pose.y - 3)
00093 go_tid = sched.new_task(turtle1_go(target))
00094 yield WaitCondition(lambda: dist(sched.turtle1_pose, target) < 0.1)
00095 sched.kill_task(go_tid)
00096 sched.printd('Meeting done')
00097 sched.resume_task(orbit_tid)
00098 coverage_tid = sched.new_task(turtle1_coverage())
00099 yield WaitDuration(6)
00100
00101 def turtle1_pose_updated(new_pose):
00102 """ We received a new pose of turtle1 from turtlesim, update condition variable in scheduler """
00103 sched.turtle1_pose = new_pose
00104
00105 def turtle2_pose_updated(new_pose):
00106 """ We received a new pose of turtle2 from turtlesim, update condition variable in scheduler """
00107 sched.turtle2_pose = new_pose
00108
00109 if __name__ == '__main__':
00110
00111 sched = TurtleScheduler()
00112 sched.new_task(turtle2_orbiting())
00113
00114
00115 rospy.init_node('teer_example_turtle')
00116
00117 rospy.wait_for_service('reset')
00118 reset_simulator = rospy.ServiceProxy('reset', EmptyServiceCall)
00119 reset_simulator()
00120 rospy.wait_for_service('clear')
00121 clear_background = rospy.ServiceProxy('clear', EmptyServiceCall)
00122 spawn_turtle = rospy.ServiceProxy('spawn', Spawn)
00123 spawn_turtle(0,0,0, "turtle2")
00124 rospy.wait_for_service('turtle1/set_pen')
00125 turtle1_set_pen = rospy.ServiceProxy('turtle1/set_pen', SetPen)
00126 rospy.wait_for_service('turtle1/teleport_absolute')
00127 turtle1_teleport = rospy.ServiceProxy('turtle1/teleport_absolute', TeleportAbsolute)
00128 rospy.wait_for_service('turtle2/set_pen')
00129 turtle2_set_pen = rospy.ServiceProxy('turtle2/set_pen', SetPen)
00130 rospy.wait_for_service('turtle2/teleport_absolute')
00131 turtle2_teleport = rospy.ServiceProxy('turtle2/teleport_absolute', TeleportAbsolute)
00132
00133 rospy.Subscriber('turtle1/pose', Pose, turtle1_pose_updated)
00134 turtle1_velocity = rospy.Publisher('turtle1/command_velocity', Velocity)
00135 rospy.Subscriber('turtle2/pose', Pose, turtle2_pose_updated)
00136 turtle2_velocity = rospy.Publisher('turtle2/command_velocity', Velocity)
00137
00138
00139 turtle1_set_pen(0,0,0,0,1)
00140 turtle2_set_pen(0,0,0,0,1)
00141 turtle1_teleport(2,2,0)
00142 turtle2_teleport(5.5,9,0)
00143 clear_background()
00144
00145
00146 sched.run()