epc.py
Go to the documentation of this file.
00001 
00002 import numpy as np, math
00003 import copy
00004 import roslib; roslib.load_manifest('equilibrium_point_control')
00005 import rospy
00006 from std_msgs.msg import Bool
00007 
00008 
00009 class EP_Generator():
00010     # @param ep_gen_func: function that returns stop, ea  where ea is the param to the control_function and  stop: string which is '' for epc motion to continue
00011     def __init__(self, ep_gen_func, control_function,
00012                  ep_clamp_func=None):
00013         self.ep_gen_func = ep_gen_func
00014         self.control_function = control_function
00015         self.ep_clamp_func = ep_clamp_func
00016 
00017 
00018 ## Class defining the core EPC function and a few simple examples.
00019 # More complex behaviors that use EPC should have their own ROS
00020 # packages.
00021 class EPC():
00022     def __init__(self, robot, epc_name = 'epc'):
00023         self.robot = robot
00024         self.stop_epc = False
00025         self.pause_epc = False
00026         rospy.Subscriber('/'+epc_name+'/stop', Bool, self.stop_cb)
00027         rospy.Subscriber('/'+epc_name+'/pause', Bool, self.pause_cb)
00028 
00029     def stop_cb(self, msg):
00030         self.stop_epc = msg.data
00031         self.pause_epc = False # stop/start overrides pause.
00032 
00033     def pause_cb(self, msg):
00034         self.pause_epc = msg.data
00035 
00036     ##
00037     # @param ep_gen - object of EP_Generator. can include any state that you want.
00038     # @param time_step: time between successive calls to equi_pt_generator
00039     # @param timeout - time after which the epc motion will stop.
00040     # @return stop (the string which has the reason why the epc
00041     # motion stopped.), ea (last commanded equilibrium angles)
00042     def epc_motion(self, ep_gen, time_step, timeout=np.inf):
00043         ep_gen_func = ep_gen.ep_gen_func
00044         control_function = ep_gen.control_function
00045         ep_clamp_func = ep_gen.ep_clamp_func
00046 
00047         rt = rospy.Rate(1/time_step)
00048         timeout_at = rospy.get_time() + timeout
00049         stop = ''
00050         ea = None
00051         while stop == '':
00052             if rospy.is_shutdown():
00053                 stop = 'rospy shutdown'
00054                 continue
00055 
00056             if self.stop_epc:
00057                 stop = 'stop_command_over_ROS'
00058                 continue
00059             
00060             if self.pause_epc:
00061                 rospy.sleep(0.1)
00062                 timeout_at += 0.101 # approximate.
00063                 continue
00064 
00065             if timeout_at < rospy.get_time():
00066                 stop = 'timed out'
00067             if stop == '':
00068                 stop, ea = ep_gen_func(ep_gen)
00069             if stop == 'reset timing':
00070                 stop = ''
00071                 t_end = rospy.get_time()
00072 
00073             if stop == '':
00074                 if ep_clamp_func != None:
00075                     ep = ea[0]
00076                     ea = list(ea)
00077                     ea[0] = ep_clamp_func(ep)
00078                     ea = tuple(ea)
00079 
00080                 control_function(*ea)
00081 
00082             rt.sleep()
00083 
00084         return stop, ea
00085 
00086     ##
00087     # this function only makes sense for arms where we have Joint
00088     # space Equilibrium Point Control.
00089     def go_jep(self, goal_jep, speed=math.radians(20)):
00090         start_jep = self.robot.get_ep()
00091         diff_jep = np.array(goal_jep) - np.array(start_jep)
00092         time_step = 0.02
00093         max_ch = np.max(np.abs(diff_jep))
00094         total_time = max_ch / speed
00095         n_steps = max(np.round(total_time / time_step + 0.5), 1)
00096         jep_step = diff_jep / n_steps
00097 
00098         def eq_gen_func(ep_gen):
00099             jep = ep_gen.jep
00100             step_num = ep_gen.step_num
00101             if step_num < n_steps:
00102                 q = list(np.array(jep) + jep_step)
00103                 stop = ''
00104             else:
00105                 q = None
00106                 stop = 'Reached'
00107             step_num += 1
00108             ep_gen.jep = q
00109             ep_gen.step_num = step_num
00110             return stop, (q, time_step*1.2)
00111         
00112         ep_gen = EP_Generator(eq_gen_func, self.robot.set_ep)
00113         ep_gen.step_num = 0
00114         ep_gen.jep = copy.copy(start_jep)
00115         return self.epc_motion(ep_gen, time_step)
00116 
00117 


equilibrium_point_control
Author(s): Advait Jain, Kelsey Hawkins. Advisor: Prof. Charlie Kemp (Healthcare Robotics Lab)
autogenerated on Wed Nov 27 2013 11:34:55