def __init__(self, expression, intensity=Default(), speed=Default(), duration=Default(), feedback_cb=None, done_cb=None): """ Makes the robot perform a facial expression, e.g. smile. The default values for the intensity, speed and duration of each gesture are specified in the robots IExpression enumeration definition. This function is asynchronous and returns an ActionHandle. :param expression: The type of expression to perform, an IExpression enumeration member (e.g.for Zeno, Expression.Smile). :type expression: IExpression subclass member :param intensity: The strength of the expression e.g. a smile with an intensity of 1.0 is the largest possible smile (normalised between 0.0 < speed <= 1.0). :type intensity: float, Default :param speed: how fast the expression is performed, e.g. a smile expression with a speed of 1.0 is performed at the fastest possible speed (normalized between 0.0 <= speed <= 1.0). If Default() then the expression is performed at its default speed. :type speed: float, Default :param duration: how long the expression lasts (seconds). If Default() then the expression is performed for its default duration. Use positive infinity for a never ending expression, hint: float('inf') :type duration: float, Default :param feedback_cb: a function that will be called when the state of the expression action changes. The function should have one parameter, which will be filled with a ExpressionActionFeedback instance. :type feedback_cb: Callable :param done_cb: a function that will be called when the expression action finishes. :type done_cb: Callable :return: an action handle to keep track of the action :rtype: MultiGoalActionHandle :raises TypeError: expression is not an IExpression member, intensity is not a float or Default, speed is not a float or Default, duration is not a float or Default, feedback_cb is not None or Callable, done_cb is not None or Callable """ TypeChecker.accepts(inspect.currentframe().f_code.co_name, (IExpression, (Default, float), (Default, float), (Default, float), (None, Callable), (None, Callable)), expression, intensity, speed, duration, feedback_cb, done_cb) IExpressionGoal.__init__(self) self.expression = expression.name if intensity is Default: self.intensity = expression.default_intensity else: self.intensity = intensity if speed is Default: self.speed = expression.default_speed else: self.speed = speed if self.duration is Default: self.duration = expression.default_duration else: self.duration = duration
def expression(self, expression, intensity=None, speed=None, duration=None): if not self.expression_found: self.wait_for_action_servers(self.expression_client) self.expression_found = True ParamFormatting.assert_types(self.expression, expression, IExpression) goal = ExpressionGoal() goal.expression = expression.name if intensity is None: goal.intensity = -1 else: ParamFormatting.assert_types(self.expression, intensity, float) ParamFormatting.assert_range(self.expression, intensity, 0.0, 1.0) goal.intensity = intensity if speed is None: goal.speed = -1 else: ParamFormatting.assert_types(self.expression, speed, float) ParamFormatting.assert_range(self.expression, speed, 0.0, 1.0) goal.speed = speed if duration is None: goal.duration = -1 else: ParamFormatting.assert_types(self.expression, duration, float) ParamFormatting.assert_greater_than(self.expression, duration, 0.0) goal.duration = duration gh = self.expression_client.send_goal(goal, done_cb=self.expression_done) ah = MultiGoalActionHandle(self.expression_client, gh) self.add_action_handle(ah) return ah
def serialize(self, buff): if self.intensity < 0.0 or self.intensity > 1.0: rospy.logwarn("ExpressionGoal intensity value of {0} is out of range, clipping to normal bounds: 0.0 <= intensity <= 1.0".format(self.intensity)) self.intensity = numpy.clip(self.intensity, 0.0, 1.0) if self.speed < 0.0 or self.speed > 1.0: rospy.logwarn("ExpressionGoal speed value of {0} is out of range, clipping to normal bounds: 0.0 <= intensity <= 1.0".format(self.speed)) self.speed = numpy.clip(self.speed, 0.0, 1.0) if self.duration < 0.0: rospy.logwarn("ExpressionGoal duration value of {0} is out of range, clipping to normal bounds: duration > 0".format(self.duration)) self.duration = max(0.0, self.duration) IExpressionGoal.serialize(buff)
def parse_parameters(self, text, audience, expression_enum, gesture_enum, tts_duration_srv): self.reset() self.audience = audience ParamFormatting.assert_types(self.parse_parameters, text, str) ParamFormatting.assert_types(self.parse_parameters, audience, Entity, Query) # if not is_callable(tts_duration_srv): # raise TypeError("parse_parameters() parameter tts_duration_srv={0} is not callable".format(tts_duration_srv)) self.sentence = SayToPlan.get_sentence(text) # Get sentence self.gaze_change_locations = SayToPlan.get_gaze_change_locations(self.sentence) # Get expressions and gestures xml_tree = ET.fromstring("<sayto>" + text + "</sayto>") seen_text = '' for node in xml_tree.iter(): if node.tag == "sayto": if node.text is not None: seen_text += node.text + " " else: start_word_i = SayToPlan.num_words(seen_text) if node.text is not None: seen_text += node.text + " " end_word_i = SayToPlan.num_words(seen_text) goal_name = node.tag if SayToPlan.enum_contains(expression_enum, goal_name): goal = ExpressionGoal() goal.expression = goal_name goal.intensity = 0.5 goal.speed = 0.5 if 'intensity' in node.attrib: goal.intensity = float(node.attrib["intensity"]) if 'speed' in node.attrib: goal.speed = float(node.attrib["speed"]) goal.duration = tts_duration_srv(self.sentence, start_word_i, end_word_i).duration self.expression_lookup[start_word_i] = goal elif SayToPlan.enum_contains(gesture_enum, goal_name): goal = GestureGoal() goal.gesture = goal_name if 'target' in node.attrib: # Check if target is Entity goal.target = node.attrib["target"] else: raise AttributeError('Please specify a target attribute for {0} gesture'.format(goal_name)) goal.duration = tts_duration_srv(self.sentence, start_word_i, end_word_i).duration self.gesture_lookup[start_word_i] = goal else: raise TypeError('No gesture or expression called: {0}'.format(goal_name)) if node.tail is not None: seen_text += node.tail + " "
def parse_parameters(self, text, audience, expression_enum, gesture_enum, tts_duration_srv): self.reset() self.audience = audience ParamFormatting.assert_types(self.parse_parameters, text, str) ParamFormatting.assert_types(self.parse_parameters, audience, Entity, Query) # if not is_callable(tts_duration_srv): # raise TypeError("parse_parameters() parameter tts_duration_srv={0} is not callable".format(tts_duration_srv)) self.sentence = SayToPlan.get_sentence(text) # Get sentence self.gaze_change_locations = SayToPlan.get_gaze_change_locations(self.sentence) # Get expressions and gestures xml_tree = ET.fromstring("<sayto>" + text + "</sayto>") seen_text = "" for node in xml_tree.iter(): if node.tag == "sayto": if node.text is not None: seen_text += node.text + " " else: start_word_i = SayToPlan.num_words(seen_text) if node.text is not None: seen_text += node.text + " " end_word_i = SayToPlan.num_words(seen_text) goal_name = node.tag if SayToPlan.enum_contains(expression_enum, goal_name): goal = ExpressionGoal() goal.expression = goal_name goal.intensity = 0.5 goal.speed = 0.5 if "intensity" in node.attrib: goal.intensity = float(node.attrib["intensity"]) if "speed" in node.attrib: goal.speed = float(node.attrib["speed"]) goal.duration = tts_duration_srv(self.sentence, start_word_i, end_word_i).duration self.expression_lookup[start_word_i] = goal elif SayToPlan.enum_contains(gesture_enum, goal_name): goal = GestureGoal() goal.gesture = goal_name if "target" in node.attrib: # Check if target is Entity goal.target = node.attrib["target"] else: raise AttributeError("Please specify a target attribute for {0} gesture".format(goal_name)) goal.duration = tts_duration_srv(self.sentence, start_word_i, end_word_i).duration self.gesture_lookup[start_word_i] = goal else: raise TypeError("No gesture or expression called: {0}".format(goal_name)) if node.tail is not None: seen_text += node.tail + " "