Go to the documentation of this file.00001
00002
00003 import rospy
00004 from std_msgs.msg import Float32
00005 from geometry_msgs.msg import Twist
00006 from rbx2_msgs.srv import *
00007 from pi_trees_ros.pi_trees_ros import *
00008 from pi_trees_lib.task_setup import *
00009
00010 class BlackBoard():
00011 def __init__(self):
00012 self.battery_level = None
00013 self.charging = None
00014
00015 class Patrol():
00016 def __init__(self):
00017 rospy.init_node("patrol_tree")
00018
00019
00020 rospy.on_shutdown(self.shutdown)
00021
00022
00023 setup_task_environment(self)
00024
00025
00026 self.blackboard = BlackBoard()
00027
00028
00029 rate = rospy.get_param('~rate', 10)
00030
00031
00032 tic = rospy.Rate(rate)
00033
00034
00035 dotfilepath = rospy.get_param('~dotfilepath', None)
00036
00037
00038 MOVE_BASE_TASKS = list()
00039
00040 n_waypoints = len(self.waypoints)
00041
00042
00043 for i in range(n_waypoints):
00044 goal = MoveBaseGoal()
00045 goal.target_pose.header.frame_id = 'map'
00046 goal.target_pose.header.stamp = rospy.Time.now()
00047 goal.target_pose.pose = self.waypoints[i % n_waypoints]
00048
00049 move_base_task = SimpleActionTask("MOVE_BASE_TASK_" + str(i), "move_base", MoveBaseAction, goal, reset_after=False)
00050
00051 MOVE_BASE_TASKS.append(move_base_task)
00052
00053
00054 goal = MoveBaseGoal()
00055 goal.target_pose.header.frame_id = 'map'
00056 goal.target_pose.header.stamp = rospy.Time.now()
00057 goal.target_pose.pose = self.docking_station_pose
00058
00059
00060 NAV_DOCK_TASK = SimpleActionTask("NAV_DOC_TASK", "move_base", MoveBaseAction, goal, reset_after=False)
00061
00062
00063 BEHAVE = Sequence("BEHAVE")
00064
00065
00066 STAY_HEALTHY = Selector("STAY_HEALTHY")
00067
00068
00069 LOOP_PATROL = Loop("LOOP_PATROL", iterations=self.n_patrols)
00070
00071
00072 BEHAVE.add_child(STAY_HEALTHY)
00073 BEHAVE.add_child(LOOP_PATROL)
00074
00075
00076 PATROL = Iterator("PATROL")
00077
00078
00079 for task in MOVE_BASE_TASKS:
00080 PATROL.add_child(task)
00081
00082
00083 LOOP_PATROL.add_child(PATROL)
00084
00085
00086 with STAY_HEALTHY:
00087
00088 MONITOR_BATTERY = MonitorTask("MONITOR_BATTERY", "battery_level", Float32, self.monitor_battery)
00089
00090
00091 CHECK_BATTERY = CallbackTask("BATTERY_OK?", self.check_battery)
00092
00093
00094 CHARGE_COMPLETE = ServiceTask("CHARGE_COMPLETE", "/battery_simulator/set_battery_level", SetBatteryLevel, 100, result_cb=self.recharge_cb)
00095
00096
00097 CHARGING = RechargeRobot("CHARGING", interval=3, blackboard=self.blackboard)
00098
00099
00100 RECHARGE = Sequence("RECHARGE", [NAV_DOCK_TASK, CHARGING, CHARGE_COMPLETE], reset_after=True)
00101
00102
00103 STAY_HEALTHY.add_child(CHECK_BATTERY)
00104 STAY_HEALTHY.add_child(RECHARGE)
00105
00106
00107 print "Patrol Behavior Tree"
00108 print_tree(BEHAVE)
00109
00110
00111 while not rospy.is_shutdown():
00112 BEHAVE.status = BEHAVE.run()
00113 tic.sleep()
00114 print_dot_tree(BEHAVE, dotfilepath)
00115
00116 def monitor_battery(self, msg):
00117
00118 self.blackboard.battery_level = msg.data
00119 return True
00120
00121 def check_battery(self):
00122
00123 if self.blackboard.charging:
00124 return False
00125
00126 if self.blackboard.battery_level is None:
00127 return None
00128 elif self.blackboard.battery_level < self.low_battery_threshold:
00129 rospy.loginfo("LOW BATTERY - level: " + str(int(self.blackboard.battery_level)))
00130 return False
00131 else:
00132 return True
00133
00134 def recharge_cb(self, result):
00135 rospy.loginfo("BATTERY CHARGED!")
00136 self.blackboard.battery_level = 100
00137 self.blackboard.charging = False
00138 rospy.sleep(2)
00139 return True
00140
00141 def shutdown(self):
00142 rospy.loginfo("Stopping the robot...")
00143 self.move_base.cancel_all_goals()
00144 self.cmd_vel_pub.publish(Twist())
00145 rospy.sleep(1)
00146
00147 class RechargeRobot(Task):
00148 def __init__(self, name, interval=3, blackboard=None):
00149 super(RechargeRobot, self).__init__(name)
00150
00151 self.name = name
00152 self.interval = interval
00153 self.blackboard = blackboard
00154
00155 self.timer = 0
00156
00157 def run(self):
00158 if self.timer == 0:
00159 rospy.loginfo("CHARGING THE ROBOT!")
00160
00161 if self.timer < self.interval:
00162 self.timer += 0.1
00163 rospy.sleep(0.1)
00164 self.blackboard.charging = True
00165 return TaskStatus.RUNNING
00166 else:
00167 return TaskStatus.SUCCESS
00168
00169 def reset(self):
00170 self.status = None
00171 self.timer = 0
00172
00173 if __name__ == '__main__':
00174 tree = Patrol()
00175