Exemplo n.º 1
0
    def sendMsg(self, snd, cmd, s, arg2="", vol=1.0, prior = 1, **kwargs):
        """
        Internal method that publishes the sound request, either directly as a
        SoundRequest to the soundplay_node or through the actionlib interface
        (which blocks until the sound has finished playing).

        The blocking behavior is nominally the class-wide setting unless it has
        been explicitly specified in the play call.
        """

        # Use the passed-in argument if it exists, otherwise fall back to the
        # class-wide setting.
        blocking = kwargs.get('blocking', self._blocking)

        msg = SoundRequest()
        msg.sound = snd
        # Threshold volume between 0 and 1.
        msg.volume = max(0, min(1, vol))
        msg.command = cmd
        msg.arg = s
        msg.arg2 = arg2
        msg.priority = prior

        rospy.logdebug('Sending sound request with volume = {}'
                       ' and blocking = {}'.format(msg.volume, blocking))

        # Defensive check for the existence of the correct communicator.
        if not blocking and not self.pub:
            rospy.logerr('Publisher for SoundRequest must exist')
            return
        if blocking and not self.actionclient:
            rospy.logerr('Action client for SoundRequest does not exist.')
            return

        if not blocking:  # Publish message directly and return immediately
            self.pub.publish(msg)
            if self.pub.get_num_connections() < 1:
                rospy.logwarn("Sound command issued, but no node is subscribed"
                              " to the topic. Perhaps you forgot to run"
                              " soundplay_node.py?")
        else:  # Block until result comes back.
            assert self.actionclient, 'Actionclient must exist'
            rospy.logdebug('Sending action client sound request [blocking]')
            self.actionclient.wait_for_server()
            goal = SoundRequestGoal()
            goal.sound_request = msg
            self.actionclient.send_goal(goal)
            self.actionclient.wait_for_result()
            rospy.logdebug('sound request response received')

        return
Exemplo n.º 2
0
    def sendMsg(self, snd, cmd, s, arg2="", vol=1.0, **kwargs):
        """
        Internal method that publishes the sound request, either directly as a
        SoundRequest to the soundplay_node or through the actionlib interface
        (which blocks until the sound has finished playing).

        The blocking behavior is nominally the class-wide setting unless it has
        been explicitly specified in the play call.
        """

        # Use the passed-in argument if it exists, otherwise fall back to the
        # class-wide setting.
        blocking = kwargs.get('blocking', self._blocking)

        msg = SoundRequest()
        msg.sound = snd
        # Threshold volume between 0 and 1.
        msg.volume = max(0, min(1, vol))
        msg.command = cmd
        msg.arg = s
        msg.arg2 = arg2

        rospy.logdebug('Sending sound request with volume = {}'
                       ' and blocking = {}'.format(msg.volume, blocking))

        # Defensive check for the existence of the correct communicator.
        if not blocking and not self.pub:
            rospy.logerr('Publisher for SoundRequest must exist')
            return
        if blocking and not self.actionclient:
            rospy.logerr('Action client for SoundRequest does not exist.')
            return

        if not blocking:  # Publish message directly and return immediately
            self.pub.publish(msg)
            if self.pub.get_num_connections() < 1:
                rospy.logwarn("Sound command issued, but no node is subscribed"
                              " to the topic. Perhaps you forgot to run"
                              " soundplay_node.py?")
        else:  # Block until result comes back.
            assert self.actionclient, 'Actionclient must exist'
            rospy.logdebug('Sending action client sound request [blocking]')
            self.actionclient.wait_for_server()
            goal = SoundRequestGoal()
            goal.sound_request = msg
            self.actionclient.send_goal(goal)
            self.actionclient.wait_for_result()
            rospy.logdebug('sound request response received')

        return
Exemplo n.º 3
0
def play_sound(sound,
               lang='',
               topic_name='robotsound',
               volume=1.0,
               wait=False):
    """
    Plays sound using sound_play server
    Args:
        sound: if sound is pathname, plays sound file located at given path
            if it is number, server plays builtin sound
            otherwise server plays sound as speech sentence
        topic-name: namespace of sound_play server
        wait: wait until sound is played
    """
    msg = SoundRequest(command=SoundRequest.PLAY_ONCE)
    if isinstance(sound, int):
        msg.sound = sound
    elif isinstance(sound, str) and Path(sound).exists():
        msg.sound = SoundRequest.PLAY_FILE
        msg.arg = sound
    elif isinstance(sound, str):
        msg.sound = SoundRequest.SAY
        msg.arg = sound
    else:
        raise ValueError

    if hasattr(msg, 'volume'):
        msg.volume = volume

    if topic_name in _sound_play_clients:
        client = _sound_play_clients[topic_name]
    else:
        client = actionlib.SimpleActionClient(topic_name, SoundRequestAction)
    client.wait_for_server()

    goal = SoundRequestGoal()
    if client.get_state() == actionlib_msgs.msg.GoalStatus.ACTIVE:
        client.cancel_goal()
        client.wait_for_result(timeout=rospy.Duration(10))
    goal.sound_request = msg
    _sound_play_clients[topic_name] = client
    client.send_goal(goal)

    if wait is True:
        client.wait_for_result(timeout=rospy.Duration(10))
    return client
Exemplo n.º 4
0
    def do_speak(self, goal):
        """The action handler.

        Note that although it responds to client after the audio play is
        finished, a client can choose
        not to wait by not calling ``SimpleActionClient.waite_for_result()``.
        """

        self.goal_text = strip_tags(goal.text)

        self.state_pub.publish(state=TTSState.SYNTHESIZING,
                               text=self.goal_text)
        res = do_synthesize(goal)
        rospy.loginfo('synthesizer returns: %s', res)

        try:
            res = json.loads(res.result)
        except ValueError as err:
            syn = 'Expecting JSON from synthesizer but got {}'.format(
                res.result)
            rospy.logerr('%s. Exception: %s', syn, err)
            self.state_pub.publish(state=TTSState.ERROR, text=syn)
            self.finish_with_result(syn)
            return

        if 'Audio File' in res:
            audio_file = res['Audio File']
            rospy.loginfo('Will play %s', audio_file)

            mut_d = mutagen.File(audio_file)
            self.length = mut_d.info.length

            self.utterance_pub.publish(self.goal_text)
            msg = SoundRequest()
            # self.sendMsg(SoundRequest.PLAY_FILE, SoundRequest.PLAY_ONCE, sound,
            #      vol=volume, **kwargs)
            msg.sound = SoundRequest.PLAY_FILE
            msg.volume = rospy.get_param("/flo_hum_vol")
            msg.command = SoundRequest.PLAY_ONCE
            msg.arg = audio_file
            msg.arg2 = ""
            goal = SoundRequestGoal()
            goal.sound_request = msg
            self.done = False
            self.sound_client.send_goal(goal,
                                        active_cb=self.sound_received,
                                        feedback_cb=self.sound_fb,
                                        done_cb=self.sound_done)
            # self.result = audio_file
            t_rate = rospy.Rate(10)
            success = True
            while not self.done:
                if self.server.is_preempt_requested():
                    self.sound_client.cancel_goal()
                    self.server.set_preempted()
                    success = False
                    break
                t_rate.sleep()
            self.state_pub.publish(state=TTSState.WAITING)
            if success:
                self.finish_with_result('completed sound play in')
        else:
            rospy.logerr('No audio file in synthesize voice result')
            self.state_pub.publish(state=TTSState.ERROR, text='no audio file')
            self.finish_with_result('no audio file')