Esempio n. 1
0
    def _publish_status(self, info_str=''):
        """Publish current state of this container."""
        # Construct messages
        with self._status_pub_lock:
            path = self._path

            #print str(structure_msg)
            # Construct status message
            #print self._container.get_active_states()
            # Guard against non-pickleable user data
            data_dict = {}
            for key, value in self._container.userdata._data.items():
                try:
                    data = pickle.dumps({key: value}, 2)
                    data_dict[key] = value
                except:
                    #rospy.logwarn('Unable to Pickle user data')
                    data_dict[key] = 'unknown'
            data = pickle.dumps(data_dict, 2)
            state_msg = SmachContainerStatus(
                Header(stamp=rospy.Time.now()), path,
                self._container.get_initial_states(),
                self._container.get_active_states(),
                pickle.dumps(data_dict, 2), info_str)
            # Publish message
            self._status_pub.publish(state_msg)
Esempio n. 2
0
 def publish_update(self, node):
     nodeid = self._nodeid(node)
     status = SmachContainerStatus()
     status.header.stamp = rospy.Time.now()
     status.path = self._pathprefix + '/' + nodeid
     status.initial_states = []
     status.active_states = [self._nodeid(node)]
     start_states_dict = node.worldstate.get_state_name_dict()
     start_states_dict['WORLDSTATE'] = str(node)  # id?
     status.local_data = pickle.dumps(start_states_dict, 2)
     status.info = 'node state'
     self._publisher_status.publish(status)
Esempio n. 3
0
    def publish_net(self, goal_node, start_node=None):
        """Publishes an RGOAP planning net, reconstructing it from the goal node.

        The goal node will be set as the active state, as its userdata is displayed.
        """
        def _add_nodes_recursively(node, structure):
            """node: beginning with the goal node"""
            structure.children.append(self._nodeid(node))

            if len(node.possible_prev_nodes) > 0:  # goal or inner node
                for prev_node in node.possible_prev_nodes:
                    structure.internal_outcomes.append('\n'.join(
                        str(e) for e in prev_node.action._effects))
                    structure.outcomes_from.append(self._nodeid(prev_node))
                    structure.outcomes_to.append(self._nodeid(node))
                    _add_nodes_recursively(prev_node, structure)
            else:  # start or dead-end node
                pass

#            if len(node.parent_nodes_path_list) == 0: # goal node
#                structure.internal_outcomes.append('succeeded')
#                structure.outcomes_from.append(self._nodeid(node))
#                structure.outcomes_to.append('None')
#            else:
#                structure.internal_outcomes.append('aborted')
#                structure.outcomes_from.append(self._nodeid(node))
#                structure.outcomes_to.append('None')

        structure = SmachContainerStructure()
        structure.header.stamp = rospy.Time.now()
        structure.path = self._pathprefix_net
        #        structure.container_outcomes = ['succeeded', 'aborted']
        _add_nodes_recursively(goal_node, structure)
        self._publisher_structure_net.publish(structure)
        _logger.info("Introspector published net with ~%s nodes",
                     len(structure.children))

        status = SmachContainerStatus()
        status.header.stamp = rospy.Time.now()
        status.path = self._pathprefix_net
        status.initial_states = [
            self._nodeid(start_node)
            if start_node is not None else 'No plan found'
        ]
        status.active_states = [self._nodeid(goal_node)]
        goal_states_dict = goal_node.worldstate.get_state_name_dict()
        goal_states_dict['WORLDSTATE'] = 'GOAL'
        status.local_data = pickle.dumps(goal_states_dict, 2)
        status.info = 'goal state'
        self._publisher_status_net.publish(status)

        rospy.sleep(5)
Esempio n. 4
0
    def _publish_status(self, info_str=''):
        """Publish current state of this container."""
        # Construct messages
        with self._status_pub_lock:
            path = self._path

            #print str(structure_msg)
            # Construct status message
            #print self._container.get_active_states()
            state_msg = SmachContainerStatus(
                Header(stamp=rospy.Time.now()), path,
                self._container.get_initial_states(),
                self._container.get_active_states(),
                pickle.dumps(self._container.userdata._data, 2), info_str)
            # Publish message
            self._status_pub.publish(state_msg)
Esempio n. 5
0
 def publish_update(self, node):
     nodeid = self._nodeid(node)
     status = SmachContainerStatus()
     status.header.stamp = rospy.Time.now()
     status.path = self._pathprefix + '/' + nodeid
     status.initial_states = []
     status.active_states = [self._nodeid(node)]
     start_states_dict = node.worldstate.get_state_name_dict()
     start_states_dict['WORLDSTATE'] = str(node) # id?
     status.local_data = pickle.dumps(start_states_dict, 2)
     status.info = 'node state'
     self._publisher_status.publish(status)
Esempio n. 6
0
    def publish(self, start_node, pathprefix=None):
        """Publishes a planned RGOAP plan

        The start node will be set as the active state, as its userdata is displayed.
        """
        def _add_nodes_recursively(node, structure):
            """node: beginning with the start node"""
            structure.children.append(self._nodeid(node))

            if not node.is_goal():
                next_node = node.parent_node()

                structure.internal_outcomes.append('\n'.join(
                    str(e) for e in node.action._effects))
                structure.outcomes_from.append(self._nodeid(node))
                structure.outcomes_to.append(self._nodeid(next_node))
                #
                #                structure.internal_outcomes.append('aborted')
                #                structure.outcomes_from.append(self._nodeid(node))
                #                structure.outcomes_to.append('None')

                _add_nodes_recursively(next_node, structure)
#            else: # goal node
#                structure.internal_outcomes.append('succeeded')
#                structure.outcomes_from.append(self._nodeid(node))
#                structure.outcomes_to.append('None')

        structure = SmachContainerStructure()
        structure.header.stamp = rospy.Time.now()
        structure.path = self._pathprefix if pathprefix is None else pathprefix
        #        structure.container_outcomes = ['succeeded', 'aborted']
        _add_nodes_recursively(start_node, structure)
        self._publisher_structure.publish(structure)
        _logger.info("Introspector published plan with ~%s nodes",
                     len(structure.children))

        status = SmachContainerStatus()
        status.header.stamp = rospy.Time.now()
        status.path = self._pathprefix
        status.initial_states = [self._nodeid(start_node)]
        status.active_states = [self._nodeid(start_node)]
        start_states_dict = start_node.worldstate.get_state_name_dict()
        start_states_dict['WORLDSTATE'] = 'START'
        status.local_data = pickle.dumps(start_states_dict, 2)
        status.info = 'initial state'
        self._publisher_status.publish(status)
    def _publish_status(self, info_str=''):
        """Publish current state of this container."""
        # Construct messages
        with self._status_pub_lock:
            path = self._path

            #print str(structure_msg)
            # Construct status message
            #print self._container.get_active_states()
            state_msg = SmachContainerStatus(
                header=Header(stamp=ROSClock().now().to_msg()),
                path=path,
                initial_states=self._container.get_initial_states(),
                active_states=self._container.get_active_states(),
                local_data=bytearray(
                    pickle.dumps(self._container.userdata._data, 2)),
                info=info_str)
            # Publish message
            self._status_pub.publish(state_msg)
Esempio n. 8
0
    def publish_net(self, goal_node, start_node=None):
        """Publishes an RGOAP planning net, reconstructing it from the goal node.

        The goal node will be set as the active state, as its userdata is displayed.
        """
        def _add_nodes_recursively(node, structure):
            """node: beginning with the goal node"""
            structure.children.append(self._nodeid(node))

            if len(node.possible_prev_nodes) > 0: # goal or inner node
                for prev_node in node.possible_prev_nodes:
                    structure.internal_outcomes.append('\n'.join(str(e) for e in prev_node.action._effects))
                    structure.outcomes_from.append(self._nodeid(prev_node))
                    structure.outcomes_to.append(self._nodeid(node))
                    _add_nodes_recursively(prev_node, structure)
            else: # start or dead-end node
                pass

#            if len(node.parent_nodes_path_list) == 0: # goal node
#                structure.internal_outcomes.append('succeeded')
#                structure.outcomes_from.append(self._nodeid(node))
#                structure.outcomes_to.append('None')
#            else:
#                structure.internal_outcomes.append('aborted')
#                structure.outcomes_from.append(self._nodeid(node))
#                structure.outcomes_to.append('None')

        structure = SmachContainerStructure()
        structure.header.stamp = rospy.Time.now()
        structure.path = self._pathprefix_net
#        structure.container_outcomes = ['succeeded', 'aborted']
        _add_nodes_recursively(goal_node, structure)
        self._publisher_structure_net.publish(structure)
        _logger.info("Introspector published net with ~%s nodes", len(structure.children))

        status = SmachContainerStatus()
        status.header.stamp = rospy.Time.now()
        status.path = self._pathprefix_net
        status.initial_states = [self._nodeid(start_node) if start_node is not None else 'No plan found']
        status.active_states = [self._nodeid(goal_node)]
        goal_states_dict = goal_node.worldstate.get_state_name_dict()
        goal_states_dict['WORLDSTATE'] = 'GOAL'
        status.local_data = pickle.dumps(goal_states_dict, 2)
        status.info = 'goal state'
        self._publisher_status_net.publish(status)

        rospy.sleep(5)
Esempio n. 9
0
    def publish(self, start_node, pathprefix=None):
        """Publishes a planned RGOAP plan

        The start node will be set as the active state, as its userdata is displayed.
        """
        def _add_nodes_recursively(node, structure):
            """node: beginning with the start node"""
            structure.children.append(self._nodeid(node))

            if not node.is_goal():
                next_node = node.parent_node()

                structure.internal_outcomes.append('\n'.join(str(e) for e in node.action._effects))
                structure.outcomes_from.append(self._nodeid(node))
                structure.outcomes_to.append(self._nodeid(next_node))
#
#                structure.internal_outcomes.append('aborted')
#                structure.outcomes_from.append(self._nodeid(node))
#                structure.outcomes_to.append('None')

                _add_nodes_recursively(next_node, structure)
#            else: # goal node
#                structure.internal_outcomes.append('succeeded')
#                structure.outcomes_from.append(self._nodeid(node))
#                structure.outcomes_to.append('None')

        structure = SmachContainerStructure()
        structure.header.stamp = rospy.Time.now()
        structure.path = self._pathprefix if pathprefix is None else pathprefix
#        structure.container_outcomes = ['succeeded', 'aborted']
        _add_nodes_recursively(start_node, structure)
        self._publisher_structure.publish(structure)
        _logger.info("Introspector published plan with ~%s nodes", len(structure.children))

        status = SmachContainerStatus()
        status.header.stamp = rospy.Time.now()
        status.path = self._pathprefix
        status.initial_states = [self._nodeid(start_node)]
        status.active_states = [self._nodeid(start_node)]
        start_states_dict = start_node.worldstate.get_state_name_dict()
        start_states_dict['WORLDSTATE'] = 'START'
        status.local_data = pickle.dumps(start_states_dict, 2)
        status.info = 'initial state'
        self._publisher_status.publish(status)
Esempio n. 10
0
    def set_initial_state(self,
                          server,
                          path,
                          initial_states,
                          initial_userdata=smach.UserData(),
                          timeout=None):
        """Set the initial state of a smach server.
        
        @type server: string
        @param server: The name of the introspection server to which this client
        should connect.

        @type path: string
        @param path: The path to the target container in the state machine.

        @type initial_states: list of string
        @param inital_state: The state the target container should take when it
        starts. This is as list of at least one state label.

        @type initial_userdata: UserData
        @param initial_userdata: The userdata to inject into the target container.

        @type timeout: rospy.Duration
        @param timeout: Timeout for this call. If this is set to None, it will not
        block, and the initial state may not be set before the target state machine
        goes active.
        """

        # Construct initial state command
        initial_status_msg = SmachContainerInitialStatusCmd(
            path=path,
            initial_states=initial_states,
            local_data=pickle.dumps(initial_userdata._data, 2))

        # A status message to receive confirmation that the state was set properly
        msg_response = SmachContainerStatus()

        # Define a local callback to just stuff a local message
        def local_cb(msg, msg_response):
            rospy.logdebug("Received status response: " + str(msg))
            msg_response.path = msg.path
            msg_response.initial_states = msg.initial_states
            msg_response.local_data = msg.local_data

        # Create a subscriber to verify the request went through
        state_sub = rospy.Subscriber(server + STATUS_TOPIC,
                                     SmachContainerStatus,
                                     callback=local_cb,
                                     callback_args=msg_response)

        # Create a publisher to send the command
        rospy.logdebug("Sending initial state command: " +
                       str(initial_status_msg.path) + " on topic '" + server +
                       INIT_TOPIC + "'")
        init_pub = rospy.Publisher(server + INIT_TOPIC,
                                   SmachContainerInitialStatusCmd,
                                   queue_size=1)
        init_pub.publish(initial_status_msg)

        start_time = rospy.Time.now()

        # Block until we get a new state back
        if timeout is not None:
            while rospy.Time.now() - start_time < timeout:
                # Send the initial state command
                init_pub.publish(initial_status_msg)

                # Filter messages that are from other containers
                if msg_response.path == path:
                    # Check if the heartbeat came back to match
                    state_match = all([
                        s in msg_response.initial_states
                        for s in initial_states
                    ])
                    local_data = smach.UserData()
                    local_data._data = pickle.loads(msg_response.local_data)
                    ud_match = all([\
                            (key in local_data and local_data._data[key] == initial_userdata._data[key])\
                            for key in initial_userdata._data])

                    rospy.logdebug("STATE MATCH: " + str(state_match) +
                                   ", UD_MATCH: " + str(ud_match))

                    if state_match and ud_match:
                        return True
                rospy.sleep(0.3)
            return False