Beispiel #1
0
 def _register_agent(self, agent_name):
     res = self._wmi.resolve_element(Element("cora:Robot", agent_name))
     if res:
         log.info("[{}]".format(self.__class__.__name__),
                  "Found robot {}, skipping registration.".format(res))
         self._robot = res
         for r in self._robot.getRelations("-1", "skiros:hasSkill"):
             self._wmi.remove_element(self._wmi.get_element(r['dst']))
         self._robot = self._wmi.get_element(self._robot.id)
     else:
         self._robot = self._wmi.instanciate(agent_name, True)
         startLocUri = self._wmi.get_template_element(
             agent_name).getRelations(pred="skiros:hasStartLocation")
         if startLocUri:
             start_location = self._wmi.instanciate(startLocUri[0]["dst"],
                                                    False, [])
             self._wmi.set_relation(self._robot._id, "skiros:at",
                                    start_location._id)
             self._robot = self._wmi.get_element(self._robot.id)
     log.info("[{}]".format(self.__class__.__name__),
              "Registered robot {}".format(self._robot))
     self._robot.setProperty(
         "skiros:SkillMgr",
         self._agent_name[self._agent_name.rfind(":") + 1:])
     self._wmi.update_element(self._robot)
Beispiel #2
0
 def _init_wm(self):
     rospack = rospkg.RosPack()
     self._skiros_dir = rospack.get_path('skiros2') + '/owl'
     self._workspace = rospy.get_param('~workspace_dir', self._skiros_dir)
     for (dirpath, dirnames, filenames) in walk(self._skiros_dir):
         for name in filenames:
             if name.find('.owl') >= 0:
                 self._ontology.load(dirpath + '/' + name)
     for (dirpath, dirnames, filenames) in walk(self._workspace):
         for name in filenames:
             if name.find('.owl') >= 0:
                 self._ontology.load(dirpath + '/' + name)
     if not self._workspace:
         self._workspace = self._skiros_dir
     self._ontology.workspace = self._workspace
     log.info("[{}]".format(self.__class__.__name__),
              "Workspace folder: {}".format(self._workspace))
     self._ontology.set_default_prefix(
         'skiros', 'http://rvmi.aau.dk/ontologies/skiros.owl#')
     init_scene = rospy.get_param('~init_scene', "")
     self._ontology.reset()
     if init_scene != "":
         self._ontology.load_context(init_scene)
     for context in rospy.get_param('~load_contexts', []):
         context_id, filename = context.split(" ")
         log.info("[{}]".format(self.__class__.__name__),
                  "Loading context {} from {}".format(context_id, filename))
         graph = self._get_context(context_id)
         graph.load_context(filename)
     # Clear prefixes from autogenerated default
     for prefix, uri1 in self._ontology._ontology.namespace_manager.store.namespaces(
     ):
         if prefix.find("default") > -1:
             self._ontology._bind(prefix, "")
     self._ontology._bind("", "")
Beispiel #3
0
 def initDomain(self):
     skills = self._wmi.resolve_elements(wmi.Element(":Skill"))
     for skill in skills:
         params = {}
         preconds = []
         holdconds = []
         postconds = []
         # Note: Only skills with pre AND post conditions are considered for planning
         for p in skill.getRelations(pred="skiros:hasParam"):
             e = self._wmi.get_element(p['dst'])
             params[e._label] = e.getProperty("skiros:DataType").value
         for p in skill.getRelations(pred="skiros:hasPreCondition"):
             e = self._wmi.get_element(p['dst'])
             if e.type.find("ConditionRelation") != -1 or e.type == "skiros:ConditionProperty" or e.type == "skiros:ConditionHasProperty":
                 preconds.append(pddl.Predicate(e, params, e.type.find("Abs") != -1))
         for p in skill.getRelations(pred="skiros:hasHoldCondition"):
             e = self._wmi.get_element(p['dst'])
             if e.type.find("ConditionRelation") != -1 or e.type == "skiros:ConditionProperty" or e.type == "skiros:ConditionHasProperty":
                 holdconds.append(pddl.Predicate(e, params, e.type.find("Abs") != -1))
         for p in skill.getRelations(pred="skiros:hasPostCondition"):
             e = self._wmi.get_element(p['dst'])
             if e.type.find("ConditionRelation") != -1 or e.type == "skiros:ConditionProperty" or e.type == "skiros:ConditionHasProperty":
                 postconds.append(pddl.Predicate(e, params, e.type.find("Abs") != -1))
         self._pddl_interface.addAction(pddl.Action(skill, params, preconds, holdconds, postconds))
     if self._verbose:
         log.info("[Domain]", self._pddl_interface.printDomain(False))
Beispiel #4
0
 def _wm_get_cb(self, msg):
     with self._times:
         to_ret = srvs.WmGetResponse()
         if msg.action == msg.GET:
             to_ret.elements.append(
                 utils.element2msg(
                     self._get_context(msg.context).get_element(
                         msg.element.id)))
         elif msg.action == msg.GET_TEMPLATE:
             to_ret.elements.append(
                 utils.element2msg(
                     self._get_context(msg.context).get_template_individual(
                         msg.element.label)))
         elif msg.action == msg.GET_RECURSIVE:
             for _, e in self._get_context(msg.context).get_recursive(
                     msg.element.id, msg.relation_filter,
                     msg.type_filter).items():
                 to_ret.elements.append(utils.element2msg(e))
         elif msg.action == msg.RESOLVE:
             for e in self._get_context(msg.context).resolve_elements(
                     utils.msg2element(msg.element)):
                 to_ret.elements.append(utils.element2msg(e))
     output = ""
     einput = utils.msg2element(msg.element)
     for e in to_ret.elements:
         output += "{} ".format(e.id)
     if self._verbose:
         log.info(
             "[WmGet]",
             "Done {} [{}]. Answer: {}. Time: {:0.3f} secs".format(
                 msg.action, einput, output, self._times.get_last()))
     to_ret.snapshot_id = self._curr_snapshot.hex
     return to_ret
Beispiel #5
0
 def _wm_modify_cb(self, msg):
     to_ret = srvs.WmModifyResponse()
     with self._times:
         if msg.action == msg.ADD:
             for e in msg.elements:
                 updated_e = self._get_context(msg.context).add_element(
                     utils.msg2element(e), msg.author)
                 to_ret.elements.append(utils.element2msg(updated_e))
             self._publish_change(msg.author,
                                  "add",
                                  elements=to_ret.elements,
                                  context_id=msg.context)
         elif msg.action == msg.UPDATE:
             for e in msg.elements:
                 self._get_context(msg.context).update_element(
                     utils.msg2element(e), msg.author)
                 er = utils.element2msg(
                     self._get_context(msg.context).get_element(e.id))
                 to_ret.elements.append(er)
             self._publish_change(msg.author,
                                  "update",
                                  elements=to_ret.elements,
                                  context_id=msg.context)
         elif msg.action == msg.UPDATE_PROPERTIES:
             for e in msg.elements:
                 self._get_context(msg.context).update_properties(
                     utils.msg2element(e), msg.author,
                     self._ontology.get_reasoner(msg.type_filter), False)
                 er = utils.element2msg(
                     self._get_context(msg.context).get_element(e.id))
                 to_ret.elements.append(er)
             self._publish_change(msg.author,
                                  "update",
                                  elements=to_ret.elements,
                                  context_id=msg.context)
         elif msg.action == msg.REMOVE:
             for e in msg.elements:
                 self._get_context(msg.context).remove_element(
                     utils.msg2element(e), msg.author)
             to_ret.elements = msg.elements
             self._publish_change(msg.author,
                                  "remove",
                                  elements=msg.elements,
                                  context_id=msg.context)
         elif msg.action == msg.REMOVE_RECURSIVE:
             for e in msg.elements:
                 self._get_context(msg.context).remove_recursive(
                     utils.msg2element(e), msg.author, msg.relation_filter,
                     msg.type_filter)
             to_ret.elements = msg.elements
             self._publish_change(msg.author,
                                  "remove_recursive",
                                  elements=msg.elements,
                                  context_id=msg.context)
     if self._verbose:
         log.info(
             "[WmModify]", "{} {} {}. Time: {:0.3f} secs".format(
                 msg.author, msg.action, [e.id for e in to_ret.elements],
                 self._times.get_last()))
     return to_ret
    def __init__(self, author_name="test"):
        """
        @brief      Interface to ontology services

                    This class uses ROS services to access and edit the
                    ontology knowledge on a server node

        @param      author_name  (string) Id used to track changes on
                                 the server
        """
        self._author_name = author_name
        self._lock = rospy.ServiceProxy('wm/lock', SetBool)
        self._ontology_query = rospy.ServiceProxy('wm/ontology/query',
                                                  srvs.WoQuery)
        self._ontology_modify = rospy.ServiceProxy('wm/ontology/modify',
                                                   srvs.WoModify)
        self._load_and_save = rospy.ServiceProxy('wm/load_and_save',
                                                 srvs.WoLoadAndSave)
        log.info("[{}] ".format(self.__class__.__name__),
                 "Waiting wm communications...")
        self._ontology_modify.wait_for_service()
        log.info("[{}] ".format(self.__class__.__name__),
                 "Wm communications active.")
        self._def_prefix = ":"
        self._sub_classes_cache = {}
        self._sub_properties_cache = {}
Beispiel #7
0
    def __init__(self):
        rospy.init_node("skill_mgr", anonymous=False)
        self.publish_runtime_parameters = False
        robot_name = rospy.get_name()
        prefix = ""
        full_name = rospy.get_param('~prefix', prefix) + ':' + robot_name[robot_name.rfind("/") + 1:]
        self.sm = SkillManager(rospy.get_param('~prefix', prefix), full_name, verbose=rospy.get_param('~verbose', True))
        self.sm.observe_task_progress(self._on_progress_update)
        self.sm.observe_tick(self._on_tick)

        # Init skills
        self._initialized = False
        self._getskills = rospy.Service('~get_skills', srvs.ResourceGetDescriptions, self._get_descriptions_cb)
        self._init_skills()
        rospy.sleep(0.5)
        self._initialized = True

        # Start communications
        self._command = rospy.Service('~command', srvs.SkillCommand, self._command_cb)
        self._monitor = rospy.Publisher("~monitor", msgs.SkillProgress, queue_size=20)
        self._tick_rate = rospy.Publisher("~tick_rate", Empty, queue_size=20)
        self._set_debug = rospy.Subscriber('~set_debug', Bool, self._set_debug_cb)
        rospy.on_shutdown(self.shutdown)
        self.init_discovery("skill_managers", robot_name)
        log.info("[{}]".format(rospy.get_name()), "Skill manager ready.")
Beispiel #8
0
 def _get_context(self, context_id):
     if context_id not in self.contexts:
         log.info("[get_context]", "Creating context: {}.".format(context_id))
         self.contexts[context_id] = IndividualsDataset(self._verbose, context_id, self._ontology._ontology)
         self.contexts[context_id].set_default_prefix('skiros', 'http://rvmi.aau.dk/ontologies/skiros.owl#')
         self.contexts[context_id].workspace = self._workspace
     return self.contexts[context_id]
Beispiel #9
0
    def _assign_task_cb(self, msg):
        """Callback for setting new goals.

        Executed whenever we receive a service call to set a new goal.

        Args:
            msg (skiros2_msgs.srv.TmSetGoals): Service message containing the goals
        """
        try:
            log.info("[Goal]", msg.goals)
            self._current_goals = msg.goals
            plan = self._task_plan()
            log.info("[Plan]", plan)
            if plan is None:
                log.warn(
                    self.class_name, "Planning failed for goals: {}".format(
                        self._current_goals))
                self._result = msgs.AssignTaskResult(1, "Planning failed.")
                self._assign_task_action.set_aborted(self._result)
                return
            if not plan:
                self._result = msgs.AssignTaskResult(2,
                                                     "No skills to execute.")
                self._assign_task_action.set_succeeded(self._result)
                return
            task = self.build_task(plan)
            self._result = msgs.AssignTaskResult(3, task.toJson())
            self._assign_task_action.set_succeeded(self._result)
            return
        except Exception, e:
            self._result = msgs.AssignTaskResult(1, str(e))
            self._assign_task_action.set_aborted(self._result)
Beispiel #10
0
 def on_wm_update(self, data):
     with self._wm_mutex:
         if self._snapshot_id == data.prev_snapshot_id and data.action != "reset":  # Discard msgs not in sync with local wm version
             self._snapshot_id = data.snapshot_id
             cur_item = self.wm_tree_widget.currentItem()
             cur_item_id = cur_item.text(1)
             if data.action == 'update' or data.action == 'update_properties':
                 for elem in data.elements:
                     elem = rosutils.msg2element(elem)
                     self._update_wm_node(elem, cur_item_id)
             elif data.action == 'add':
                 for elem in data.elements:
                     elem = rosutils.msg2element(elem)
                     if not self._add_wm_node(elem):
                         self._snapshot_id = ""
             elif data.action == 'remove' or data.action == 'remove_recursive':
                 for elem in data.elements:
                     elem = rosutils.msg2element(elem)
                     self._remove_wm_node(elem)
             # reselect current item
             items = self.wm_tree_widget.findItems(cur_item_id, Qt.MatchRecursive | Qt.MatchFixedString, 1)
             if items:
                 self.wm_tree_widget.setCurrentItem(items[0])
             #self._save_log(data, "wm_edit")
         elif data.stamp > self._snapshot_stamp or self._snapshot_id == "":  # Ignores obsolete msgs
             log.info("[wm_update]", "Wm not in sync, querying wm scene")
             self.create_wm_tree()
Beispiel #11
0
 def _wm_query_rel_cb(self, msg):
     # TODO: get rid of this. Replace implementation with a standard SPARQL query
     to_ret = srvs.WmQueryRelationsResponse()
     with self._times:
         to_ret.matches = [utils.relation2msg(x) for x in self._ontology.get_relations(utils.msg2relation(msg.relation))]
     if self._verbose:
         log.info("[wmQueryRelation]", "Query: {} Answer: {}. Time: {:0.3f} secs".format(msg.relation, to_ret.matches, self._times.get_last()))
     return to_ret
Beispiel #12
0
 def _add_prefix(self, uri, prefix=None):
     if prefix is None:
         prefix = uri[uri.rfind("/") + 1:].lower()
         if prefix.rfind(".") != -1:
             prefix = prefix[:prefix.rfind(".")]
     uri = uri + "#"
     self._bind(prefix, uri)
     log.info("[{}]".format(self.__class__.__name__), "Set id: {} for ontology: {}".format(prefix, uri))
     return prefix
Beispiel #13
0
 def _unregister(self, element):
     """
     @brief Removes an element from tf publish list
     """
     if element.id in self._tf_list:
         log.info(
             "[AauSpatialReasoner] Stop publishing {}.".format(element))
         element.setProperty("skiros:PublishTf", False)
         del self._tf_list[element.id]
         self._trigger_children_update(element)
Beispiel #14
0
 def execute(self, skill, processor=Serial):
     if not self.initAndParametrize(skill):
         return False
     if self._verbose:
         log.info("Execute {}.".format(skill._label))
     self.addInExecutionTree(skill, processor)
     skill.hold()
     self.mergeParams(skill)  # Update params
     self.forward.memorize(skill, "execute")
     return True
Beispiel #15
0
 def forget(self):
     # TODO: possible mess with parentNode in execution tree...
     skill, tag = self.forward.forget()
     if self._verbose:
         log.info("Undo {} {}.".format(skill._label, tag))
     if tag == 'execute':
         self.revert(skill)
     elif tag == 'postExecute':
         self.postRevert(skill)
     return (skill, tag)
Beispiel #16
0
 def add_task(self, task):
     """
     @brief Add a new task to the list
     """
     root = skill.Root("root", self._local_wm)
     for i in task:
         log.info("[SkillManager]", "Add task {}:{} \n {}".format(i.type, i.name, i.ph.printState()))
         root.addChild(skill.SkillWrapper(i.type, i.name, self._instanciator))
         root.last().specifyParamsDefault(i.ph)
     return self._ticker.add_task(root, root.id)
Beispiel #17
0
 def start(self, visitor, uid):
     if uid in BtTicker._tasks_to_pause:
         log.info("[start]", "Resuming task {}.".format(uid))
         del BtTicker._tasks_to_pause[uid]
     else:
         log.info("[start]", "Starting task {}.".format(uid))
     if not self.is_running():
         BtTicker._visitor = visitor
         BtTicker._process = Process(target=BtTicker._run, args=(self, True))
         BtTicker._process.start()
         return True
Beispiel #18
0
 def postExecute(self, skill):
     """
     @brief Tick a skill
     """
     skill.specifyParams(self._params)#Re-apply parameters.... Important!
     self.syncParams(skill.params)
     self._printTracked(skill._params, "[{}:SetParams] ".format(skill.type))
     state = self._postExecute(skill)
     if self._verbose:
         log.info("[VisitorExecute]", "{}".format(skill.printState(self._verbose)))
     self.mergeParams(skill)  # Update params
     return state
Beispiel #19
0
 def checkHold(self, skill):
     """
     @brief Check hold conditions
     """
     if skill.checkHoldCond(self._verbose):
         if self._verbose:
             log.info("[ground]", "Hold-conditions fail for skill {}".format(skill.printInfo()))
         self.processPreempt(skill)
         skill.checkHoldCond()#This ensure the skill ends printing the failed conditions
         return skill.state
     else:
         return State.Running
Beispiel #20
0
 def _load_and_save_cb(self, msg):
     with self._times:
         if msg.action == msg.SAVE:
             self._get_context(msg.context).save_context(msg.filename)
         elif msg.action == msg.LOAD:
             self._get_context(msg.context).load_context(msg.filename)
             self._publish_change("", "reset", elements=[], context_id=msg.context)
         else:
             return srvs.WoLoadAndSaveResponse(False)
     if self._verbose:
         log.info("[wmLoadAndSave]", "{} {} to file {}. Time: {:0.3f} secs".format(msg.action, msg.context, self._get_context(msg.context).filename, self._times.get_last()))
     return srvs.WoLoadAndSaveResponse(True)
 def _run(self, _):
     """
     @brief Tick tasks at 25hz
     """
     BtTicker._finished_skill_ids = dict()
     rate = rospy.Rate(25)
     log.info("[BtTicker]", "Execution starts.")
     while BtTicker._tasks:
         self._tick()
         rate.sleep()
         self._tick_cb()
     log.info("[BtTicker]", "Execution stops.")
Beispiel #22
0
 def _register(self, element, parent_frame):
     """
     @brief Adds an element to tf publish list
     """
     if element.id in self._to_rebase_list:
         del self._to_rebase_list[element.id]
     if not element.id in self._tf_list:
         log.info("[AauSpatialReasoner] Publishing {} parent: {}".format(element, parent_frame))
         self._trigger_children_update(element)
     element.setData(":Orientation", self._quaternion_normalize(element.getData(":Orientation")))
     element.setProperty("skiros:PublishTf", True)
     self._tf_list[element.id] = element
Beispiel #23
0
 def syncParams(self, params):
     for k, p in params.items():
         vs = p.values
         if p.dataTypeIs(Element):
             for i in reversed(range(0, len(vs))):
                 if vs[i].getIdNumber() >= 0:
                     try:
                         vs[i] = self._wm.get_element(vs[i].id)
                     except WmException:
                         log.info("[syncParams]", "{} was deleted, removing from parameters".format(vs[i].id))
                         vs.pop(i)
             p.values = vs
Beispiel #24
0
 def inferUnvalidParams(self, skill):
     #print '{}: {} '.format(skill._label, self.printParams(skill._params))
     unvalid_params = skill.checkPreCond(self._verbose)
     if unvalid_params:
         log.info("[{}] Reset unvalid params {}".format(skill._label, unvalid_params))
         for k in unvalid_params:
             skill._params.setDefault(k)
             p = skill._params.getParam(k)
             if p.dataTypeIs(Element()) and p.getValue().getIdNumber() >= 0:
                 skill._params.specify(k, self._wm.get_element(p.getValue()._id))
         return self._autoParametrizeBB(skill)
     return True
Beispiel #25
0
 def _wm_set_rel_cb(self, msg):
     with self._times:
         if msg.value:
             temp = "+"
             self._ontology.add_relation(utils.msg2relation(msg.relation), msg.author, is_relation=True)
             self._publish_change(msg.author, "add", relation=msg.relation)
         else:
             temp = "-"
             self._ontology.remove_relation(utils.msg2relation(msg.relation), msg.author, is_relation=True)
             self._publish_change(msg.author, "remove", relation=msg.relation)
     if self._verbose:
         log.info("[wmSetRelCb]", "[{}] {} Time: {:0.3f} secs".format(temp, msg.relation, self._times.get_last()))
     return srvs.WmSetRelationResponse(True)
Beispiel #26
0
 def tryOther(self, skill):
     """
     @brief If the skill label is not specified, try other instances
     """
     if skill.label != "":
         return False
     ignore_list = [skill._instance.label]
     while self._instanciator.assign_instance(skill, ignore_list):
         log.info("tryOther", "Trying skill {}".format(skill._instance.label))
         ignore_list.append(skill._instance.label)
         if self._ground(skill):
             return True
     return False
Beispiel #27
0
 def instance(self, plugin, args_dict):
     names, req, opt = self.signature(plugin)
     log.info(
         self.__class__.__name__, "Instantiating " + str(plugin) +
         " with arguments " + str(args_dict) + "  || REQUIRED: " +
         str(req) + " OPTIONAL: " + str(opt.keys()))
     p = None
     try:
         p = plugin(**args_dict)
     except Exception as e:
         log.error(self.__class__.__name__,
                   "  ERROR while instantiating: " + str(e))
     return p
Beispiel #28
0
 def postExecute(self, skill, remember=True):
     skill.specifyParams(self._params)  # Re-apply parameters, after processing the sub-tree.... Important, thay have been modified by the subtree!
     if self._verbose:
         log.info("postExecute {}.".format(skill._label))
     if not self._postExecute(skill):
         return False
     self.mergeParams(skill)  # Update params
     self.forward.memorize(skill, "postExecute")
     if skill._label != self.getExecutionParent()._label:
         log.error("postExecution", "{} trying to close before the parent {}".format(skill._label, self.getExecutionParent()._label))
         raise KeyError()
     self.popParentNode()
     if id(skill) in self._bound:
         self.postExecute(self._bound.pop(id(skill)))
     return True
Beispiel #29
0
 def load_context(self, filename):
     """
     @brief Load context from file
     """
     if filename:
         self._filename = filename
     if not path.isfile(self.filedir):
         log.error("[load_context]",
                   "Can't load {}. File not found. ".format(self.filename))
         return
     self._stop_reasoners()
     self.reset()
     self.context.parse(self.filedir, format='turtle')
     self._start_reasoners()
     log.info("[load_context]", "Loaded context {}. ".format(self.filename))
Beispiel #30
0
 def _reset(self):
     self._tf_list = {}
     self._linked_list = {}
     self._to_rebase_list = {}
     root = self._wmi.get_element("skiros:Scene-0")
     self._spatial_rels = self._wmi.get_sub_properties("skiros:spatiallyRelated")
     if root.hasProperty("skiros:FrameId"):
         self._base_frame = root.getProperty("skiros:FrameId").value
     else:
         self._base_frame = "map"
         log.info(self.__class__.__name__, "Adding FrameId {} to scene.".format(self._base_frame))
         root.setProperty("skiros:FrameId", self._base_frame)
         self._wmi.update_element(root, self.__class__.__name__)
     for e in self._wmi.get_recursive(root.id, "skiros:spatiallyRelated").values():
         self.parse(e, "add")