Пример #1
0
def get_kb_update(instances, d):
    kua = KnowledgeUpdateServiceArrayRequest()
    n = len(instances)
    assert (n == len(d) and n == len(d[0]))
    for i in xrange(n):
        for j in xrange(n):
            ki = KnowledgeItem()
            ki.knowledge_type = ki.FUNCTION
            ki.attribute_name = 'distance'
            kv = KeyValue()
            kv.key = 'a'
            kv.value = instances[i]
            ki.values.append(kv)
            kv = KeyValue()
            kv.key = 'b'
            kv.value = instances[j]
            ki.values.append(kv)
            ki.function_value = d[i][j]
            kua.update_type += np.array(kua.ADD_KNOWLEDGE).tostring()
            kua.knowledge.append(ki)
    return kua
Пример #2
0
    def load_fact_message(self, attribute, uploaded_instance, item, domain):
        fact_msg = KnowledgeItem()
        fact_msg.knowledge_type = KnowledgeItem.FACT
        fact_msg.instance_type = ""
        fact_msg.instance_name = ""
        fact_msg.attribute_name = attribute
        fact_msg.function_value = 0.0
        output_value = KeyValue()
        output_value.key = (self._predicate_param_label_list[fact_msg.attribute_name])[
            0
        ]
        output_value.value = uploaded_instance
        fact_msg.values.append(output_value)

        # write to knowledge base
        ## For insert domain, the attribute container needs to be added as a fact, without second term
        if ("in" == attribute) or ("on" == attribute):
            output_value = KeyValue()
            output_value.key = (
                self._predicate_param_label_list[fact_msg.attribute_name]
            )[1]
            output_value.value = self.msg_to_instance_name(item, domain)
            fact_msg.values.append(output_value)

            ##Robocup hack for finals
            ## Removing instance of objects to be picked form rotation table CB02
            if "CB02" == output_value.value or "CB01" == output_value.value:
                print "Rotating table knowledge base not updateing for object", uploaded_instance
                self.object_to_delete_goals.append(uploaded_instance)
                return
            if "SH01" == output_value.value or "SH02" == output_value.value:
                print "Removing object tot pick from shelf ,", uploaded_instance
                self.object_to_delete_goals.append(uploaded_instance)
                return

        # print (fact_msg)
        self.write_to_knowledge_base(
            fact_msg, self.knowledge_update_service["ADD_KNOWLEDGE"]
        )
Пример #3
0
    def fill_order(self, order, attribute, first, second, count=-1):
        #In transportationtask sometimes the destination is not there in inventory
        #Needs to add fact about the inventory
        if 'destination' == second:
            name = self.load_instance_message(KnowledgeItem.INSTANCE, 'destination', order)
        fact_msg = KnowledgeItem()
        fact_msg.knowledge_type = KnowledgeItem.FACT
        fact_msg.instance_type = ''
        fact_msg.instance_name = ''
        fact_msg.attribute_name = attribute
        fact_msg.function_value = 0.0
        output_value = KeyValue()
        output_value.key = (self._predicate_param_label_list[fact_msg.attribute_name])[0]
        output_value.value = self.msg_to_instance_name(order, first, count)

        fact_msg.values.append(output_value)
        output_value = KeyValue()
        output_value.key = (self._predicate_param_label_list[fact_msg.attribute_name])[1]
        #in order the container or location doesnt have the count
        output_value.value = self.msg_to_instance_name(order, second )
        fact_msg.values.append(output_value)
        self.write_to_knowledge_base(fact_msg, self.knowledge_update_service['ADD_GOAL'] )
    def clearAllMarkers(self):
        edges = MarkerArray()
        marker = Marker()
        marker.header.stamp = rospy.Time.now()
        marker.header.frame_id = "map"
        marker.ns = "waypoint_edges"
        marker.id = 0
        marker.action = Marker.DELETEALL
        edges.markers.append(marker)
        self.edge_line_publisher.publish(edges)

        # clear databases
        for node, data in self.waypoint_graph.nodes_iter(data=True):
            self.message_store.delete(data["id"])
            self.knowledge_service(
                update_type=self.knowledge_service.request_class.
                REMOVE_KNOWLEDGE,
                knowledge=[
                    KnowledgeItem(knowledge_type=KnowledgeItem.INSTANCE,
                                  instance_type="waypoint",
                                  instance_name=node)
                ])
    def load_initial_state_new_assumptions(self):
        self.clear_knowledge_client.call()

        for instance in self.initial_instances.instances:
            knowledge = KnowledgeItem()
            knowledge.knowledge_type = KnowledgeItem.INSTANCE
            knowledge.instance_type = "object"
            knowledge.instance_name = instance
            self.update_knowledge_client(
                KnowledgeUpdateServiceRequest.ADD_KNOWLEDGE, knowledge)

        for goal in self.initial_goal.attributes:
            self.update_knowledge_client(
                KnowledgeUpdateServiceRequest.ADD_GOAL, goal)

        for fact in self.initial_facts.attributes:
            self.update_knowledge_client(
                KnowledgeUpdateServiceRequest.ADD_KNOWLEDGE, fact)

        rospy.loginfo(
            "Initial state loaded successfuly. Now loading assumptions:")
        for i in range(0, len(self.current_assumptions)):
            self.update_assumption(i, self.current_assumptions[i])
Пример #6
0
def distance(msg, params):

    distance = float('inf')
    ret_value = []

    # create KB update client
    rospy.wait_for_service('/strategic/rosplan_knowledge_base/update_array')
    rospy.wait_for_service(
        '/tactical_execution/rosplan_knowledge_base/update_array')
    rospy.wait_for_service(
        '/strategic/rosplan_interface_strategic_control/add_mission_goal')
    update_kb = rospy.ServiceProxy(
        '/strategic/rosplan_knowledge_base/update_array',
        KnowledgeUpdateServiceArray)
    update_kb_tactical = rospy.ServiceProxy(
        '/tactical_execution/rosplan_knowledge_base/update_array',
        KnowledgeUpdateServiceArray)
    update_strategic_goals = rospy.ServiceProxy(
        '/strategic/rosplan_interface_strategic_control/add_mission_goal',
        KnowledgeUpdateServiceArray)

    # add new ground_wp to the KB
    ground_wps = rospy.get_param("/ground_wp")
    try:
        pos = [float(msg.data[0]), float(msg.data[1]), 0.0, 0.0]
        for wp in ground_wps:

            # check if wp is the new one
            if close_point(pos, ground_wps[wp], 0.01):

                # upload new wp to KB
                kus = KnowledgeUpdateServiceArrayRequest()
                kus.update_type += np.array(kus.ADD_KNOWLEDGE).tostring()
                ki = KnowledgeItem()
                ki.instance_type = "ground"
                ki.instance_name = wp
                ki.knowledge_type = ki.INSTANCE
                kus.knowledge.append(ki)
                res = update_kb(kus)
                res = update_kb_tactical(kus)

                # Oberve added waypoint (if not original)
                if len(wp) >= 10 and int(wp[9:]) > 4:
                    kus = KnowledgeUpdateServiceArrayRequest()
                    kus.update_type += np.array(kus.ADD_GOAL).tostring()
                    ki = KnowledgeItem()
                    ki.knowledge_type = ki.FACT
                    ki.attribute_name = 'observed'
                    kv = KeyValue()
                    kv.key = 'wp'
                    kv.value = wp
                    ki.values.append(kv)
                    kus.knowledge.append(ki)
                    try:
                        res = update_strategic_goals(kus)
                    except:
                        print "Something Happened"

                # add new wp to the prm
                prm_nodes = rospy.get_param("/prm/wp")
                prm_edges = rospy.get_param("/prm/edge")

                rospy.set_param("/prm/wp/" + wp, ground_wps[wp])
                prm_nodes[wp] = ground_wps[wp]
                prm_edges[wp] = {}
                for node in prm_nodes:
                    if node == wp:
                        continue
                    d = sqrt((ground_wps[wp][0] - prm_nodes[node][0]) *
                             (ground_wps[wp][0] - prm_nodes[node][0]) +
                             (ground_wps[wp][1] - prm_nodes[node][1]) *
                             (ground_wps[wp][1] - prm_nodes[node][1]) +
                             (ground_wps[wp][2] - prm_nodes[node][2]) *
                             (ground_wps[wp][2] - prm_nodes[node][2]))
                    if d <= 4:
                        rospy.set_param("/prm/edge/" + wp + "/" + node, d)
                        rospy.set_param("/prm/edge/" + node + "/" + wp, d)
                        prm_edges[wp][node] = d
                        prm_edges[node][wp] = d

                # add new distances for each other wp
                kus = KnowledgeUpdateServiceArrayRequest()
                for other_wp in ground_wps:
                    if other_wp == wp:
                        continue

                    # don't check frame_id
                    if not type(ground_wps[other_wp]) is list:
                        continue

                    # run dijkstra
                    distance = dijkstra(wp, other_wp, prm_nodes, prm_edges)

                    if distance > 0:
                        # upload distances to KB
                        ki = KnowledgeItem()
                        ki.knowledge_type = ki.FUNCTION
                        ki.attribute_name = "distance"
                        kv = KeyValue()
                        kv.key = 'wp1'
                        kv.value = other_wp
                        ki.values.append(kv)
                        kv = KeyValue()
                        kv.key = 'wp2'
                        kv.value = wp
                        ki.values.append(kv)
                        ki.function_value = distance
                        kus.update_type += np.array(
                            kus.ADD_KNOWLEDGE).tostring()
                        kus.knowledge.append(ki)

                        ki = KnowledgeItem()
                        ki.knowledge_type = ki.FUNCTION
                        ki.attribute_name = "distance"
                        kv = KeyValue()
                        kv.key = 'wp1'
                        kv.value = wp
                        ki.values.append(kv)
                        kv = KeyValue()
                        kv.key = 'wp2'
                        kv.value = other_wp
                        ki.values.append(kv)
                        ki.function_value = distance
                        kus.update_type += np.array(
                            kus.ADD_KNOWLEDGE).tostring()
                        kus.knowledge.append(ki)
                res = update_kb(kus)
                res = update_kb_tactical(kus)

                # add new visibility between sky and ground
                sky_wps = rospy.get_param("/sky_wp")
                added_visibility = False

                kus = KnowledgeUpdateServiceArrayRequest()
                for sky_wp in sky_wps:
                    if check_visibility(ground_wps[wp], sky_wps[sky_wp]):

                        ki = KnowledgeItem()
                        ki.knowledge_type = ki.FACT
                        ki.attribute_name = "can_observe"
                        kv = KeyValue()
                        kv.key = 'wp1'
                        kv.value = sky_wp
                        ki.values.append(kv)
                        kv = KeyValue()
                        kv.key = 'wp2'
                        kv.value = wp
                        ki.values.append(kv)
                        kus.update_type += np.array(
                            kus.ADD_KNOWLEDGE).tostring()
                        kus.knowledge.append(ki)

                        added_visibility = True

                if added_visibility:
                    res = update_kb(kus)
                    res = update_kb_tactical(kus)

                # create new sky_wp if no visibility was created
                if not added_visibility:

                    new_sky_wp_name = "sky_above_" + wp

                    # upload new wp to KB
                    kus = KnowledgeUpdateServiceArrayRequest()
                    kus.update_type += np.array(kus.ADD_KNOWLEDGE).tostring()
                    ki = KnowledgeItem()
                    ki.instance_type = "sky"
                    ki.instance_name = new_sky_wp_name
                    ki.knowledge_type = ki.INSTANCE
                    kus.knowledge.append(ki)
                    res = update_kb(kus)
                    res = update_kb_tactical(kus)

                    # create new sky_wp and add to param server
                    new_sky_wp = list(ground_wps[wp])
                    new_sky_wp[2] = new_sky_wp[2] + 8
                    rospy.set_param("/sky_wp" + new_sky_wp_name, new_sky_wp)

                    # add visibility of other ground wps for the new sky wp
                    kus = KnowledgeUpdateServiceArrayRequest()
                    for gwp in ground_wps:

                        if check_visibility(ground_wps[gwp], new_sky_wp):

                            ki = KnowledgeItem()
                            ki.knowledge_type = ki.FACT
                            ki.attribute_name = "can_observe"
                            kv = KeyValue()
                            kv.key = 'wp1'
                            kv.value = new_sky_wp_name
                            ki.values.append(kv)
                            kv = KeyValue()
                            kv.key = 'wp2'
                            kv.value = wp
                            ki.values.append(kv)
                            kus.update_type += np.array(
                                kus.ADD_KNOWLEDGE).tostring()
                            kus.knowledge.append(ki)

                    if len(kus.knowledge) > 0:
                        res = update_kb(kus)
                        res = update_kb_tactical(kus)

                break
    except rospy.ServiceException, e:
        rospy.logerr(
            "KCL (%s) Failed to update knowledge base: %s" % rospy.get_name(),
            e.message)
    def load_inventory_to_knowledge_base(self):

        if (None == self._inventory_message):
            return
        
        #Creating the message
        instance_msg = KnowledgeItem()

        for item in self._inventory_message.items:
            #Attribute on which the fact is written
            attribute = None
            object_instance_list = []

            #################################
            ## Uploading INSTANCE of Objects
            #################################
            #check if the instance_id is present
            if (0 != item.object.instance_id.data):
                #uploading the instance of object
                text = self.object_type[item.object.type.data] 
                if (text == 'CONTAINER_BOX_BLUE' or text == 'CONTAINER_BOX_RED'):
                    print ("NOT ADDING CONTAINERS")
                    continue
                else:
                    name = self.load_instance_message('object', item )
                    object_instance_list.append(name)

            else:
                #if not then
                #check quantity and loop on quantity
                if (0 != item.quantity.data):
                    for count in range(item.quantity.data):
                        #uploading the instance of object
                        name = self.load_instance_message('object', item, count)
                        object_instance_list.append(name)
                else:
                    rospy.loginfo("Instance ID not provided as well as quantity ")
                    #uploading the instance of object without ID and quantity 
                    text = self.object_type[item.object.type.data] 
                    if (text == 'CONTAINER_BOX_BLUE' or text == 'CONTAINER_BOX_RED'):
                        continue
                    else:
                        name = self.load_instance_message('object', item)
                        object_instance_list.append(name)
                        self.event_out.publish("e_failure")

            #Flag for identifying if location or container
            instance_type_identifyer = None

            #################################
            ## Uploading INSTANCE of locations
            #################################
            #check if location exist
            if (0 != item.location.type.data):
                name = self.load_instance_message('location', item)

                #fill fact "Object" ON "location"
                attribute = 'on'
                instance_type_identifyer = 'location'

            #################################
            ## Uploading INSTANCE of CONTAINER
            #################################
            ## Removing uploading instances of container doing only while task loading
            ## Causing counting problem in both inventory loading and task loading
            ## since counting is done in both and in task we sometimes dont load task for all the containers 
            ## there are situations in which the container numbering differs from inventory and task loading
            '''
            elif (0 != item.container.type.data):
                name = self.load_instance_message('container', item)
                #upload fact "Object" IN "container"
                attribute = 'in'
                instance_type_identifyer = 'container'
            '''
            #################################
            ## Uploading FACTS
            #################################

            if (attribute):
                for uploaded_instance in object_instance_list:
                    self.load_fact_message(attribute, uploaded_instance, item, instance_type_identifyer)

                attribute = None

        #Resetting the flag when the inventory contained some data
        rospy.loginfo('Received inventory data updated knowledge base')
        self.start_inventory_flag = False
        # Triggering the completion of the inventory update
        self.inventory_update_complete_flag = True

        #clearning inventory message
        self._inventory_message = None


        self.event_out.publish("e_done")
Пример #8
0
    def load_order_to_knowledge_base(self):

        rospy.loginfo("Loading task info to knowledge base")
        # Creating the message
        instance_msg = KnowledgeItem()
        for task in self._tasks.tasks:
            ####################################################################
            # Transportation task
            ####################################################################
            if atwork_ros_msgs.msg.Task.TRANSPORTATION == task.type.data:
                # The task is transportation
                # find the object, its destination

                if 0 != task.transportation_task.container.type_id.data:
                    # container is available
                    # some order contain container in order but not in inventory, so need to add fact explicitly
                    name = self.load_instance_message(
                        "destination", task.transportation_task
                    )
                    container_name = self.load_instance_message(
                        "container", task.transportation_task
                    )
                    if container_name:
                        # same the knowledge about the initial location of the container is missin, adding it
                        self.load_fact_message(
                            "on",
                            container_name,
                            task.transportation_task,
                            "destination",
                        )
                        self.load_fact_message(
                            "container",
                            container_name,
                            task.transportation_task,
                            "destination",
                        )
                        self.load_fact_message(
                            "heavy",
                            container_name,
                            task.transportation_task,
                            "destination",
                        )

                        object_name = self.fill_order(
                            task.transportation_task,
                            "in",
                            "object",
                            "container",
                            container_name=container_name,
                        )
                        if object_name:
                            self.load_fact_message(
                                "insertable",
                                object_name,
                                task.transportation_task,
                                "destination",
                            )

                elif 0 != task.transportation_task.destination.instance_id.data:
                    # if (0 != task.transportation_task.destination.instance_id.data): //Add when 'in' domain is not present
                    # In transportationtask sometimes the destination is not there in inventory
                    # Needs to add fact about the inventory
                    name = self.load_instance_message(
                        "destination", task.transportation_task
                    )
                    # container not available but destination available
                    insertable_object_name = self.fill_order(
                        task.transportation_task, "on", "object", "destination"
                    )
                    ## IF PP01 then we need to load some facts
                    if 5 == task.transportation_task.destination.type.data:
                        self.load_fact_message(
                            "on", "PP01_CAVITY", task.transportation_task, "destination"
                        )
                        self.load_fact_message(
                            "container",
                            "PP01_CAVITY",
                            task.transportation_task,
                            "destination",
                        )
                        self.load_fact_message(
                            "heavy",
                            "PP01_CAVITY",
                            task.transportation_task,
                            "destination",
                        )
                        if insertable_object_name:
                            self.load_fact_message(
                                "insertable",
                                insertable_object_name,
                                task.transportation_task,
                                "destination",
                            )
                        self.load_instance_message_PP01("object")
                else:
                    # both container and destination not available
                    rospy.logerr("No Goal set")

                if (0 != task.transportation_task.container.type_id.data) and (
                    0 != task.transportation_task.destination.instance_id.data
                ):
                    ##Both container and destination available
                    ###ERL2016 the containers need not moved so we dont need to add goal for the containers
                    ###Add the below line when the container needs to be transported
                    # self.fill_order(task.transportation_task, 'on', 'container', 'destination' )
                    ###The Fact about the initial location of the container is missing
                    pass

        rospy.loginfo("Task info upload completed")
Пример #9
0
    def generate_knowledge_base(self):

        # Remove earlier entries from knowledge database
        self.clear_knowledge()

        empty_waypoints = []
        valid_occupants =  self.objects['drone'] + self.objects['turtlebot']
        for loc in self.objects['waypoint'] + self.objects['airwaypoint']:
            valid = False
            if loc in self.at:
                for o in self.at[loc]:
                    valid = True if (o in valid_occupants) else valid

            if not valid:
                empty_waypoints.append(loc)

       # Set up waypoint distances
        for wp1 in self.objects['waypoint']:
            for wp2 in self.objects['waypoint']:
                kitem = KnowledgeItem()
                kitem.knowledge_type = KnowledgeItem.FUNCTION
                kitem.attribute_name = "move-duration"
                kitem.values = [KeyValue('from', wp1), KeyValue('to', wp2)]
                kitem.function_value = self.waypoint_distance(wp1,wp2)
                self.update_knowledge(update_type=KnowledgeUpdateServiceEnum.ADD_KNOWLEDGE, knowledge=kitem)

        for wp1 in self.objects['airwaypoint']:
            for wp2 in self.objects['airwaypoint']:
                kitem = KnowledgeItem()
                kitem.knowledge_type = KnowledgeItem.FUNCTION
                kitem.attribute_name = "move-duration"
                kitem.values = [KeyValue('from', wp1), KeyValue('to', wp2)]
                kitem.function_value = self.waypoint_distance(wp1,wp2)
                self.update_knowledge(update_type=KnowledgeUpdateServiceEnum.ADD_KNOWLEDGE, knowledge=kitem)

        # Set empty for agents and waypoints
        for obj in self.objects['drone'] + self.objects['turtlebot'] + empty_waypoints:
            kitem = KnowledgeItem()
            kitem.knowledge_type = KnowledgeItem.FACT
            kitem.values = [KeyValue('aw_object', obj)]
            kitem.attribute_name = 'empty'
            self.update_knowledge(update_type=KnowledgeUpdateServiceEnum.ADD_KNOWLEDGE, knowledge=kitem)

        # Add agents
        for key, items in self.objects.iteritems():
            for item in items:
                kitem = KnowledgeItem()
                kitem.knowledge_type = KnowledgeItem.INSTANCE
                kitem.instance_type = key
                kitem.instance_name = item
                self.update_knowledge(update_type=KnowledgeUpdateServiceEnum.ADD_KNOWLEDGE, knowledge=kitem)

        # Add locations for agents and boxes
        for key, values in self.at.iteritems():
            for value in values:
                kitem = KnowledgeItem()
                kitem.knowledge_type = KnowledgeItem.FACT
                kitem.values = [KeyValue('object', value), KeyValue('waypoint', key)]
                kitem.attribute_name = 'at'
                self.update_knowledge(update_type=KnowledgeUpdateServiceEnum.ADD_KNOWLEDGE, knowledge=kitem)
        
        # Add state airborne to drones at air waypoints
        for air_wp in self.objects['airwaypoint']:
            for drone in self.objects['drone']:
                if drone in self.at[air_wp]:
                    kitem = KnowledgeItem()
                    kitem.knowledge_type = KnowledgeItem.FACT
                    kitem.values = [KeyValue('drone', drone)]
                    kitem.attribute_name = 'airborne'
                    self.update_knowledge(update_type=KnowledgeUpdateServiceEnum.ADD_KNOWLEDGE, knowledge=kitem)

        # Set relation between air and ground waypoints
        for air, ground in zip(self.objects['airwaypoint'], self.objects['waypoint']):
            kitem = KnowledgeItem()
            kitem.knowledge_type = KnowledgeItem.FACT
            kitem.values = [KeyValue('airwaypoint', air), KeyValue('waypoint', ground)]
            kitem.attribute_name = 'over'
            self.update_knowledge(update_type=KnowledgeUpdateServiceEnum.ADD_KNOWLEDGE, knowledge=kitem)

        # Set rescued persons
        for person in self.rescued:
            kitem = KnowledgeItem()
            kitem.knowledge_type = KnowledgeItem.FACT
            kitem.values = [KeyValue('person', person)]
            kitem.attribute_name = 'handled'
            self.update_knowledge(update_type=KnowledgeUpdateServiceEnum.ADD_KNOWLEDGE, knowledge=kitem)

        # Set goals, each person should be handled
        for person in self.objects['person']:
            kitem = KnowledgeItem()
            kitem.knowledge_type = KnowledgeItem.FACT
            kitem.values = [KeyValue('person', person)]
            kitem.attribute_name = 'handled'
            self.update_knowledge(update_type=KnowledgeUpdateServiceEnum.ADD_GOAL, knowledge=kitem)
Пример #10
0
    def load_inventory_to_knowledge_base(self):

        if (None == self._inventory_message):
            return

        #Creating the message
        instance_msg = KnowledgeItem()


        for item in self._inventory_message.items:
            #Attribute on which the fact is written
            attribute = None
            object_instance_list = []

            #################################
            ## Uploading INSTANCE of Objects
            #################################
            #check if the instance_id is present
            if (0 != item.object.instance_id.data):
                #uploading the instance of object
                name = self.load_instance_message(KnowledgeItem.INSTANCE, 'object', item )
                object_instance_list.append(name)

            else:
                #if not then
                #check quantity and loop on quantity
                if (0 != item.quantity.data):
                    for count in range(item.quantity.data):
                        #uploading the instance of object
                        name = self.load_instance_message(KnowledgeItem.INSTANCE, 'object', item, count)
                        object_instance_list.append(name)
                else:
                    rospy.loginfo("Instance ID not provided as well as quantity ")
                    #uploading the instance of object without ID and quantity 
                    name = self.load_instance_message(KnowledgeItem.INSTANCE, 'object', item)
                    object_instance_list.append(name)
                    self.event_out.publish("e_failure")

            #Flag for identifying if location or container
            instance_type_identifyer = None

            #################################
            ## Uploading INSTANCE of locations
            #################################
            #check if location exist
            if (0 != item.location.type.data):
                name = self.load_instance_message(KnowledgeItem.INSTANCE, 'location', item)

                #fill fact "Object" ON "location"
                attribute = 'on'
                instance_type_identifyer = 'location'

            #################################
            ## Uploading INSTANCE of CONTAINER
            #################################
            elif (0 != item.container.type.data):
                name = self.load_instance_message(KnowledgeItem.INSTANCE, 'container', item)
                #upload fact "Object" IN "container"
                attribute = 'in'
                instance_type_identifyer = 'container'

            #################################
            ## Uploading FACTS
            #################################

            if (attribute):
                for uploaded_instance in object_instance_list:
                    fact_msg = KnowledgeItem()
                    fact_msg.knowledge_type = KnowledgeItem.FACT
                    fact_msg.instance_type = ''
                    fact_msg.instance_name = ''
                    fact_msg.attribute_name = attribute
                    fact_msg.function_value = 0.0
                    output_value = KeyValue()
                    output_value.key = (self._predicate_param_label_list[fact_msg.attribute_name])[0]
                    output_value.value = uploaded_instance
                    fact_msg.values.append(output_value)
                    output_value = KeyValue()
                    output_value.key = (self._predicate_param_label_list[fact_msg.attribute_name])[1]
                    output_value.value = self.msg_to_instance_name(item, \
                                                        instance_type_identifyer)
                    fact_msg.values.append(output_value)
                    self.write_to_knowledge_base(fact_msg, self.knowledge_update_service['ADD_KNOWLEDGE'])

                attribute = None

            #Resetting the flag when the inventory contained some data
            rospy.loginfo('Received inventory data updated knowledge base')
            self.start_inventory_flag = False
            # Triggering the completion of the inventory update
            self.inventory_update_complete_flag = True

        #clearning inventory message
        self._inventory_message = None


        self.event_out.publish("e_done")
    def insertMarker(self, position, name=None, frame_id="map"):

        if name is None:
            name = "wp{0}".format(self.next_waypoint_id)
        self.next_waypoint_id += 1

        # update rosplan knowledge base and insert waypoint if successful
        if self.knowledge_service(
                update_type=self.knowledge_service.request_class.ADD_KNOWLEDGE,
                knowledge=[
                    KnowledgeItem(knowledge_type=KnowledgeItem.INSTANCE,
                                  instance_type="waypoint",
                                  instance_name=name)
                ]):

            int_marker = InteractiveMarker()
            int_marker.header.frame_id = frame_id
            int_marker.pose.position = position
            int_marker.scale = 0.5

            int_marker.name = name
            int_marker.description = "Waypoint: {0}".format(name)

            # markers a moveable in the plane
            control = InteractiveMarkerControl()
            control.orientation.w = 1
            control.orientation.x = 0
            control.orientation.y = 1
            control.orientation.z = 0
            control.interaction_mode = InteractiveMarkerControl.MOVE_PLANE

            menu_handler = MenuHandler()
            menu_handler.insert("Connect/Disconnect",
                                callback=self.processFeedback)
            menu_handler.insert("Clear", callback=self.processFeedback)
            menu_handler.insert("Remove", callback=self.processFeedback)

            # make a box which also moves in the plane
            control.markers.append(self._makeMarker(int_marker))
            control.always_visible = True
            int_marker.controls.append(control)

            # we want to use our special callback function
            self.server.insert(int_marker, self.processFeedback)
            menu_handler.apply(self.server, int_marker.name)
            # set different callback for POSE_UPDATE feedback
            self.server.setCallback(int_marker.name, self.moveFeedback,
                                    InteractiveMarkerFeedback.POSE_UPDATE)
            self.server.applyChanges()

            # push to scene database
            pstamped = PoseStamped()
            pstamped.header.frame_id = frame_id
            pstamped.pose = self.server.get(int_marker.name).pose
            pstamped.pose.orientation.w = 1.0  # otherwise movebase will reject the quaternion

            id = self.message_store.insert_named(int_marker.name, pstamped)
            # insert into graph
            self.waypoint_graph.add_node(int_marker.name, {"id": id})

        else:
            rospy.logerr(
                "(Interactive_Waypoint_Server) Failed to insert waypoint {0}. Knowledge database service call returned error."
                .format(name))
    def make_srv_req_to_KB(
        knowledge_type_is_instance=True,
        instance_type="",
        instance_name="",
        attribute_name="",
        values=[],
        update_type_is_knowledge=True,
    ):
        """
        make a service call to ``rosplan_knowledge_base`` (mongodb)

        :param knowledge_type_is_instance: type of knowledge
        :type knowledge_type_is_instance: bool
        :param instance_type: type of instance
        :type instance_type: str
        :param instance_name: name of instance
        :type instance_name: str
        :param attribute_name: name of attribute
        :type attribute_name: str
        :param values: values for attribute
        :type value: list (tuple (str, str))
        :param update_type_is_knowledge: type of update to be performed
        :type update_type_is_knowledge: bool
        :return: success
        :rtype: bool

        example 1:
        **upload instance**: youbot has one ``dynamixel`` ``gripper``.

        .. code-block:: bash

            rosservice call /rosplan_knowledge_base/update "update_type: 0
                knowledge:
                knowledge_type: 0
                instance_type: 'gripper'
                instance_name: 'dynamixel'
                attribute_name: ''
                values: {}
                function_value: 0.0";

        To perform the following using this function

        .. code-block:: python

            ProblemUploader.make_srv_req_to_KB(knowledge_type_is_instance=True,
                                               instance_type='gripper',
                                               instance_name='dynamixel')

        example 2:
        **upload fact**: object ``o4`` is on location ``S3``

        .. code-block:: bash

            rosservice call /rosplan_knowledge_base/update "update_type: 0
                knowledge:
                knowledge_type: 1
                instance_type: ''
                instance_name: ''
                attribute_name: 'on'
                values:
                - {key: 'o', value: 'o4'}
                - {key: 'l', value: 'S3'}
                function_value: 0.0";

        To perform the following using this function

        .. code-block:: python

            ProblemUploader.make_srv_req_to_KB(knowledge_type_is_instance=False,
                                               attribute_name='on',
                                               values=[('o', 'o4'),
                                                       ('l', 'S3')])

        """
        msg = KnowledgeItem()
        if knowledge_type_is_instance:
            msg.knowledge_type = KnowledgeItem.INSTANCE
            msg.instance_type = instance_type
            msg.instance_name = instance_name.upper()
        else:
            msg.knowledge_type = KnowledgeItem.FACT
            msg.attribute_name = attribute_name
            msg.values = [KeyValue(i[0], i[1].upper()) for i in values]

        update_kb_topic = "/rosplan_knowledge_base/update"
        rospy.loginfo("Waiting for " + update_kb_topic)
        rospy.wait_for_service(update_kb_topic)

        try:
            update_kb = rospy.ServiceProxy(update_kb_topic,
                                           KnowledgeUpdateService)
            if update_type_is_knowledge:
                response = update_kb(Req.ADD_KNOWLEDGE, msg)
            else:
                response = update_kb(Req.ADD_GOAL, msg)

        except rospy.ServiceException as e:
            rospy.logerr("Service call failed: %s" % e)

        if response.success:
            rospy.loginfo("KB updated successfully.")
            return True
        else:
            rospy.logerror("KB update failed.")
            return False
    def load_inventory_to_knowledge_base(self):

        if (None == self._inventory_message):
            return
        
        #Creating the message
        instance_msg = KnowledgeItem()

        for item in self._inventory_message.items:
            #Attribute on which the fact is written
            attribute = None
            object_instance_list = []

            #################################
            ## Uploading INSTANCE of Objects
            #################################
            #check if the instance_id is present
            if (0 != item.object.instance_id.data):
                #uploading the instance of object
                name = self.load_instance_message('object', item )
                object_instance_list.append(name)

            else:
                #if not then
                #check quantity and loop on quantity
                if (0 != item.quantity.data):
                    for count in range(item.quantity.data):
                        #uploading the instance of object
                        name = self.load_instance_message('object', item, count)
                        object_instance_list.append(name)
                else:
                    rospy.loginfo("Instance ID not provided as well as quantity ")
                    #uploading the instance of object without ID and quantity 
                    name = self.load_instance_message('object', item)
                    object_instance_list.append(name)
                    self.event_out.publish("e_failure")

            #Flag for identifying if location or container
            instance_type_identifyer = None

            #################################
            ## Uploading INSTANCE of locations
            #################################
            #check if location exist
            if (0 != item.location.type.data):
                name = self.load_instance_message('location', item)

                #fill fact "Object" ON "location"
                attribute = 'on'
                instance_type_identifyer = 'location'

            #################################
            ## Uploading INSTANCE of CONTAINER
            #################################
            elif (0 != item.container.type.data):
                name = self.load_instance_message('container', item)
                #upload fact "Object" IN "container"
                attribute = 'in'
                instance_type_identifyer = 'container'

            #################################
            ## Uploading FACTS
            #################################

            if (attribute):
                for uploaded_instance in object_instance_list:
                    self.load_fact_message(attribute, uploaded_instance, item, instance_type_identifyer)

                attribute = None

        #Resetting the flag when the inventory contained some data
        rospy.loginfo('Received inventory data updated knowledge base')
        self.start_inventory_flag = False
        # Triggering the completion of the inventory update
        self.inventory_update_complete_flag = True

        #clearning inventory message
        self._inventory_message = None


        self.event_out.publish("e_done")
Пример #14
0
#!/usr/bin/python2
import rospy
from rosplan_knowledge_msgs.srv import KnowledgeUpdateService
from rosplan_knowledge_msgs.msg import KnowledgeItem
from diagnostic_msgs.msg import KeyValue

if __name__ == "__main__":
    rospy.init_node("init_ceres_rosplan")

    rospy.loginfo("(Init_Ceres_Rosplan) Waiting for knowledge update service")

    rospy.wait_for_service("kcl_rosplan/update_knowledge_base")
    rospy.loginfo(
        "(Init_Ceres_Rosplan) Initializing robot 'ceres' to waypoint 'wp0'")
    update_service = rospy.ServiceProxy("kcl_rosplan/update_knowledge_base",
                                        KnowledgeUpdateService)

    update_service(
        update_type=KnowledgeUpdateService._request_class.ADD_KNOWLEDGE,
        knowledge=KnowledgeItem(knowledge_type=KnowledgeItem.INSTANCE,
                                instance_type='robot',
                                instance_name='ceres'))
    update_service(
        update_type=KnowledgeUpdateService._request_class.ADD_KNOWLEDGE,
        knowledge=KnowledgeItem(knowledge_type=KnowledgeItem.FACT,
                                attribute_name='robot_at',
                                values=[
                                    KeyValue(key='v', value='ceres'),
                                    KeyValue(key='wp', value='wp0')
                                ]))
Пример #15
0
def _generate_predicate(type_name, **kwargs):
    new_type_name, is_negative = _is_predicate_negative(type_name)
    return KnowledgeItem(KB_ITEM_FACT, "", "", new_type_name,
                         dict_to_keyval(kwargs), 0.0, is_negative)
Пример #16
0
    def rosplan_update_knowledge(self,
                                 knowledge_type,
                                 instance_type,
                                 instance_name,
                                 attribute_name,
                                 values,
                                 function_value=0.0,
                                 update_type='ADD_KNOWLEDGE'):
        '''
        This generic function receives knowledge parameters and does a service call
        to rosplan knowledge base (mongodb)

        rosplan_update_knowledge() = rosplan service call add knowledge

        Example 1:
        # upload instance : youbot has one dynamixel gripper (dynamixel - gripper)
        rosservice call /kcl_rosplan/update_knowledge_base "update_type: 0 # ADD_KNOWLEDGE = 0
            knowledge:
            knowledge_type: 0 # INSTANCE = 0
            instance_type: 'gripper'
            instance_name: 'dynamixel'
            attribute_name: ''
            values:
            -{}
            function_value: 0.0";
        # (on o4 S3)

        example 2: object4 (o4) is on location S3
        # upload fact :
        rosservice call /kcl_rosplan/update_knowledge_base "update_type: 0 # ADD_KNOWLEDGE = 0
            knowledge:
            knowledge_type: 1 # FACT = 1
            instance_type: ''
            instance_name: ''
            attribute_name: 'on'
            values:
            - {key: 'o', value: 'o4'}
            - {key: 'l', value: 'S3'}
            function_value: 0.0";

        '''
        msg = KnowledgeItem()
        if knowledge_type == 0:
            # instance
            msg.knowledge_type = KnowledgeItem.INSTANCE  # INSTANCE (rosplan_knowledge_msgs/msg/KnowledgeItem.msg)
            msg.instance_type = instance_type
            msg.instance_name = instance_name
            msg.attribute_name = ''
        elif knowledge_type == 1:
            # fact
            msg.knowledge_type = KnowledgeItem.FACT  # FACT (rosplan_knowledge_msgs/msg/KnowledgeItem.msg)
            msg.instance_type = ''
            msg.instance_name = ''
            msg.attribute_name = attribute_name
            for each in values:
                msg.values.append(KeyValue(each[0], each[1]))
        else:
            rospy.logerr(
                'error: no information will be uploaded, Knowledge type should be INSTANCE = 0, or FACT = 1'
            )
            return False
        msg.function_value = function_value
        rospy.logdebug('======msg=========')
        rospy.logdebug(msg)
        rospy.logdebug('================')
        rospy.loginfo(
            'Waiting for /kcl_rosplan/update_knowledge_base to become available...'
        )
        rospy.wait_for_service('/kcl_rosplan/update_knowledge_base')
        try:
            update_kb = rospy.ServiceProxy(
                '/kcl_rosplan/update_knowledge_base', KnowledgeUpdateService)
            # get response
            if update_type == 'ADD_KNOWLEDGE':
                response = update_kb(
                    KnowledgeUpdateServiceRequest.ADD_KNOWLEDGE, msg)
            elif update_type == 'ADD_GOAL':
                response = update_kb(KnowledgeUpdateServiceRequest.ADD_GOAL,
                                     msg)
            elif update_type == 'REMOVE_KNOWLEDGE':
                response = update_kb(
                    KnowledgeUpdateServiceRequest.REMOVE_KNOWLEDGE, msg)
            elif update_type == 'REMOVE_GOAL':
                response = update_kb(KnowledgeUpdateServiceRequest.REMOVE_GOAL,
                                     msg)
            else:
                rospy.logerr(
                    'Error : Unknown update_type, admisible values are ADD_KNOWLEDGE, ADD_GOAL, REMOVE_KNOWLEDGE and REMOVE_GOAL'
                )
                rospy.logwarn('Knowledge base not updated...!')
        except rospy.ServiceException, e:
            rospy.logerr('Service call failed: %s' % e)
            return False
        except rospy.ServiceException, e:
            rospy.logerr("KCL (%s) Failed to update knowledge base: %s" % rospy.get_name(), e.message)
        skip_check = True

    # load and check KB for waypoints
    waypoints = []
    if rospy.has_param(waypoint_namespace):
        waypoints = rospy.get_param(waypoint_namespace)
    if len(params[0]) != len(waypoints):
        del params[0][:]
        # waypoints not properly loaded yet, add to KB
        rospy.loginfo("KCL: (%s) Waypoints not loaded into KB yet, skipping visibility check" % rospy.get_name())
        try:
            kus = KnowledgeUpdateServiceArrayRequest()
            for wp in waypoints:
                ki = KnowledgeItem()
                ki.instance_type = "waypoint"
                ki.instance_name = wp
                ki.knowledge_type = ki.INSTANCE
                kus.update_type += np.array(kus.ADD_KNOWLEDGE).tostring()
                kus.knowledge.append(ki)
                params[0].append(wp)
            res = update_kb(kus)
        except rospy.ServiceException, e:
            rospy.logerr("KCL (%s) Failed to update knowledge base: %s" % rospy.get_name(), e.message)
        skip_check = True

    if skip_check:
        return ret_value

    attributes = get_kb_attribute("doughnut_visible_from")