Advertisement
tiagopinto

Untitled

Oct 29th, 2018
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.74 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. import rospy
  4.  
  5. import smach
  6. import importlib
  7. import actionlib
  8.  
  9. from task_manager_common.printer import Printer
  10. from task_manager_common.status_publisher import SkillStatusPublisher
  11. from task_manager_common.ros_interface import ROSInterface
  12.  
  13. from pprint import pprint
  14. import ast
  15.  
  16. class SkillState(smach.State):
  17.     def __init__(self, outcomes=None, io_keys=None):
  18.         _outcomes = outcomes if outcomes is not None else ["preempted", "aborted", "succeeded"]
  19.         _io_keys = io_keys if io_keys is not None else ["skillId", "actionName", "actionGoal",
  20.                                                         "actionType", "actionResult"]
  21.         smach.State.__init__(self, outcomes=_outcomes, io_keys=_io_keys)
  22.  
  23.         self.ud = None
  24.  
  25.         robot_id = ROSInterface.get_ROS_param('task_manager/robot_configuration/robot_id')
  26.  
  27.         self.printer = Printer(robot_id, 'TaskManager')
  28.         self.status_publisher = SkillStatusPublisher()
  29.  
  30.     def check_preemption(self):
  31.         if self.preempt_requested():
  32.             self.service_preempt()
  33.             self.status_publisher.preempted()
  34.             self.printer.logwarn("Skill Preempted!")
  35.             return True
  36.         else:
  37.             return False
  38.  
  39.     def request_preempt(self):
  40.         """Overload the preempt request method just to spew an error."""
  41.         smach.State.request_preempt(self)
  42.         self.status_publisher.preempted()
  43.  
  44.     def set_status_publisher_keys(self, ud):
  45.         self.status_publisher.set_skill_id(str(ud.skillId))
  46.         if ud.actionName.startswith('/'):
  47.             self.status_publisher.set_skill_label(str(ud.actionName)[1:])
  48.             self.status_publisher.set_skill_type(str(ud.actionName)[1:])
  49.         else:
  50.             self.status_publisher.set_skill_label(str(ud.actionName))
  51.             self.status_publisher.set_skill_type(str(ud.actionName))
  52.  
  53.     @staticmethod
  54.     def get_task_id():
  55.         try:
  56.             task_id = rospy.get_param('task_manager/current_task')
  57.         except:
  58.             task_id = None
  59.         return task_id
  60.  
  61.  
  62. class SkillSetup(SkillState):
  63.     def __init__(self, outcomes=None, io_keys=None):
  64.         SkillState.__init__(self)
  65.         #self.goal = None
  66.  
  67.     @staticmethod
  68.     def load_pkg_module(action_type):
  69.         pkg = action_type[:action_type.find('/', 0, len(action_type))]  # -> wait_skill_msgs
  70.         module_ = action_type[action_type.find('/', 0, len(action_type)) + 1:-6]  # -> WaitSkill
  71.         return pkg, module_
  72.  
  73.     def load_type(self, action_type):
  74.         pkg, module_ = self.load_pkg_module(action_type)
  75.  
  76.         try:
  77.             module_ref = importlib.import_module('.msg', pkg)  # -> module 'wait_skill_msgs.msg'
  78.         except Exception as e:
  79.             rospy.logerr(str(e))
  80.             return None
  81.         return module_ref
  82.  
  83.     @staticmethod
  84.     def load_action(module_, module_ref):
  85.         type_instance = module_ref.__getattribute__(module_ + "Action")
  86.         return type_instance
  87.  
  88.     @staticmethod
  89.     def load_goal(module_, module_ref):
  90.         goal_instance = module_ref.__getattribute__(module_ + "Goal")()  # -> waitTime: 0
  91.         return goal_instance
  92.  
  93.     @staticmethod
  94.     def load_result(module_, module_ref):
  95.         result_instance = module_ref.__getattribute__(module_+"Result")()  # ->  percentage: 0 skillStatus: ''
  96.         return result_instance
  97.  
  98.     def action_name_constructor(self, goal, ud):
  99.         return ud.actionName
  100.  
  101.     @staticmethod
  102.     def goal_parser(ud):
  103.         for data, value in ud.actionGoal.iteritems():
  104.             print data, value
  105.  
  106.         return ud.actionGoal
  107.  
  108.     def action_goal_constructor(self, goal, ud):
  109.         return goal
  110.  
  111.     def get_goal_parameter(self, param):
  112.         pass
  113.         print 'GOAL GOAL GOAL'
  114.         print type(self.goal)
  115.         print self.goal
  116.         #for item, value in self.goal.iteritems():
  117.         #    print item, value
  118.         pprint(dir(self.goal))
  119.         if hasattr(self.goal, param):
  120.             param_value = self.goal[param]
  121.             return param_value
  122.         else:
  123.             raise AttributeError('Skill Goal does not have %s value defined' % param)
  124.  
  125.  
  126.     def action_type_constructor(self, action_type, ud):
  127.         return action_type
  128.  
  129.     def action_result_constructor(self, result, ud):
  130.         return result
  131.  
  132.     def execute(self, ud):
  133.         self.ud = ud
  134.         self.set_status_publisher_keys(ud)
  135.         pkg, module_ = self.load_pkg_module(ud.actionType)
  136.         module_ref = self.load_type(ud.actionType)
  137.  
  138.         self.printer.tag_by_index(2, self.get_task_id())
  139.         self.printer.tag_by_index(3, module_)
  140.  
  141.         self.printer.loginfo('Started Setup')
  142.         if self.check_preemption():
  143.             return 'preempted'
  144.         try:
  145.             print ud.actionGoal
  146.             print type(ud.actionGoal)
  147.             action_type = self.load_action(module_, module_ref)
  148.             goal = self.load_goal(module_, module_ref)
  149.             goals_dict = self.goal_parser(ud)
  150.             result = self.load_result(module_, module_ref)
  151.             ud.actionName = self.action_name_constructor(goals_dict, ud)
  152.             ud.actionGoal = self.action_goal_constructor(goal, ud)
  153.             ud.actionType = self.action_type_constructor(action_type, ud)
  154.             ud.actionResult = self.action_result_constructor(result, ud)
  155.  
  156.  
  157.         except Exception as e:
  158.             self.printer.logerr(str(e))
  159.             self.status_publisher.aborted()
  160.             self.printer.logerr('Skill Aborted on Setup')
  161.             return 'aborted'
  162.         return "succeeded"
  163.  
  164.  
  165. class SkillExecution(SkillState):
  166.     def __init__(self, outcomes=None, io_keys=None):
  167.         SkillState.__init__(self)
  168.         self.client = None
  169.         self.action_name = None
  170.         self.action_type = None
  171.         self.action_goal = None
  172.  
  173.     def action_client_setup(self, action_name, action_type):
  174.         try:
  175.             self.client = actionlib.SimpleActionClient(action_name, action_type)
  176.             self.status_publisher.setup()
  177.         except Exception as e:
  178.             self.printer.logerr('Error on Action Client Setup: ' + str(e))
  179.             raise Exception(e)
  180.  
  181.     def wait_for_server(self, wait_for_server_timeout=10):
  182.         self.printer.loginfo('Waiting for server...')
  183.         if not self.client.wait_for_server(rospy.Duration(wait_for_server_timeout)):
  184.             self.printer.logerr("Skill Action Client Error: Timed out (%i's) while trying to find Action Server"
  185.                                 % wait_for_server_timeout)
  186.             self.status_publisher.aborted()
  187.             return False
  188.         return True
  189.  
  190.     def send_goal(self, goal):
  191.         try:
  192.             self.printer.loginfo("Sending goal to '%s' Server" % self.action_name)
  193.             self.client.send_goal(goal=goal,  feedback_cb=self.action_feedback_callback,
  194.                                   done_cb=self.action_done_callback, active_cb=self.action_active_callback)
  195.         except Exception as e:
  196.             self.printer.logerr('Error on goal sending: ' + str(e))
  197.             self.status_publisher.aborted()
  198.             raise Exception(e)
  199.  
  200.     def wait_for_result(self, time_out=300):
  201.         self.printer.loginfo("Waiting response from '%s' Server" % self.action_name)
  202.         if not self.client.wait_for_result(rospy.Duration(time_out)):
  203.             self.printer.logerr("Skill Action Client Error: Timed out (%i's) while waiting for %s Action Server Result"
  204.                                 % (time_out, self.action_name))
  205.             return False
  206.         return True
  207.  
  208.     def state_handler(self):
  209.         if self.client.get_state() == 2:
  210.             self.printer.logwarn('Skill Preempted')
  211.             self.service_preempt()
  212.             return 'preempted'
  213.         elif self.client.get_state() == 4:
  214.             self.printer.logerr('Skill Aborted')
  215.             self.status_publisher.aborted()
  216.             return 'aborted'
  217.         elif self.client.get_state() == 3:
  218.             #self.printer.loginfo('Skill succeeded')
  219.             return 'succeeded'
  220.  
  221.     # NOTE: action_feedback_cb can be overloaded on the derived class
  222.     def action_feedback_callback(self, feedback):
  223.         self.printer.loginfo("Feedback Received: %i%% Executed. Status: %s."
  224.                              % (int(feedback.percentage), feedback.skillStatus))
  225.  
  226.     # NOTE: action_done_cb can be overloaded on the derived class
  227.     def action_done_callback(self, status, result):
  228.         self.printer.loginfo('Skill Execution Completed.')
  229.  
  230.     # NOTE: action_active_cb can be overloaded on the derived class
  231.     def action_active_callback(self):
  232.         self.printer.loginfo('Goal sent to the %s Server.' % self.action_name)
  233.  
  234.     def execute(self, ud):
  235.         self.action_name = ud.actionName[1:] if ud.actionName.startswith('/') else ud.actionName
  236.         self.action_type = ud.actionType
  237.         self.action_goal = ud.actionGoal
  238.         self.ud = ud
  239.         self.set_status_publisher_keys(ud)
  240.  
  241.         self.printer.tag_by_index(2, self.get_task_id())
  242.         self.printer.tag_by_index(3, self.action_name)
  243.         self.printer.loginfo('Started Execution')
  244.  
  245.         if self.check_preemption():
  246.             return 'preempted'
  247.         try:
  248.             self.action_client_setup(ud.actionName, ud.actionType)
  249.             self.status_publisher.execution()
  250.             if not self.wait_for_server(wait_for_server_timeout=10):  # TODO: get param from task_manager_configurations
  251.                 return 'aborted'
  252.             self.send_goal(ud.actionGoal)
  253.             if not self.wait_for_result(time_out=300):  # TODO: get param from task_manager_configurations
  254.                 return 'aborted'
  255.             state_handle = self.state_handler()
  256.             if state_handle != 'succeeded':
  257.                 return state_handle
  258.             result = self.client.get_result()
  259.             ud.actionResult = result
  260.         except Exception as e:
  261.             self.printer.logerr('Error on Action Client Setup: ' + str(e))
  262.             raise Exception(e)
  263.         return "succeeded"
  264.  
  265.     def request_preempt(self):
  266.  
  267.         """Overload the preempt request method just to spew an error."""
  268.  
  269.         self.client.cancel_all_goals()
  270.         smach.State.request_preempt(self)
  271.         self.status_publisher.preempted()
  272.         self.printer.logwarn("Skill Execution Preempted!")
  273.  
  274.  
  275. class SkillAnalysis(SkillState):
  276.     def __init__(self, outcomes=None, io_keys=None):
  277.         _outcomes = self.set_outcomes()
  278.  
  279.         SkillState.__init__(self, _outcomes)
  280.         self.action_name = None
  281.  
  282.     def result_analysis(self, action_result):
  283.         try:
  284.             if action_result.percentage == 100:
  285.                 self.printer.loginfo('Skill Succeeded')
  286.                 return 'succeeded'
  287.             else:
  288.                 self.printer.logerr('Skill aborted on Analysis')
  289.                 return 'aborted'
  290.         except Exception as e:
  291.             self.printer.logerr('Error on Action Client Analysis: ' + str(e))
  292.             raise Exception(e)
  293.  
  294.     def set_outcomes(self):
  295.         return ["preempted", "aborted", "succeeded"]
  296.  
  297.     def execute(self, ud):
  298.         self.action_name = ud.actionName[1:] if ud.actionName.startswith('/') else ud.actionName
  299.         self.ud = ud
  300.         self.printer.tag_by_index(2, self.get_task_id())
  301.         self.printer.tag_by_index(3, self.action_name)
  302.         self.set_status_publisher_keys(ud)
  303.         if self.check_preemption():
  304.             return 'preempted'
  305.         self.status_publisher.succeeded()
  306.         return self.result_analysis(action_result=ud.actionResult)
  307.  
  308.     def request_preempt(self):
  309.  
  310.         """Overload the preempt request method just to spew an error."""
  311.  
  312.         smach.State.request_preempt(self)
  313.         self.status_publisher.preempted()
  314.         self.printer.logwarn("Skill Analysis Preempted!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement