Source code for pomdp_py.problems.multi_object_search.domain.observation

"""
Defines the Observation for the 2D Multi-Object Search domain;

Origin: Multi-Object Search using Object-Oriented POMDPs (ICRA 2019)
(extensions: action space changes, different sensor model, gridworld instead of topological graph)

Observation:

    :code:`{objid : pose(x,y) or NULL}`.
    The sensor model could vary;
    it could be a fan-shaped model as the original paper, or
    it could be something else. But the resulting observation
    should be a map from object id to observed pose or NULL (not observed).
"""

import pomdp_py


###### Observation ######
[docs] class ObjectObservation(pomdp_py.Observation): """The xy pose of the object is observed; or NULL if not observed""" NULL = None def __init__(self, objid, pose): self.objid = objid if type(pose) == tuple and len(pose) == 2 or pose == ObjectObservation.NULL: self.pose = pose else: raise ValueError("Invalid observation %s for object" % (str(pose), objid)) def __hash__(self): return hash((self.objid, self.pose)) def __eq__(self, other): if not isinstance(other, ObjectObservation): return False else: return self.objid == other.objid and self.pose == other.pose
[docs] class MosOOObservation(pomdp_py.OOObservation): """Observation for Mos that can be factored by objects; thus this is an OOObservation.""" def __init__(self, objposes): """ objposes (dict): map from objid to 2d pose or NULL (not ObjectObservation!). """ self._hashcode = hash(frozenset(objposes.items())) self.objposes = objposes
[docs] def for_obj(self, objid): if objid in self.objposes: return ObjectObservation(objid, self.objposes[objid]) else: return ObjectObservation(objid, ObjectObservation.NULL)
def __hash__(self): return self._hashcode def __eq__(self, other): if not isinstance(other, MosOOObservation): return False else: return self.objposes == other.objposes def __str__(self): return "MosOOObservation(%s)" % str(self.objposes) def __repr__(self): return str(self)
[docs] def factor(self, next_state, *params, **kwargs): """Factor this OO-observation by objects""" return { objid: ObjectObservation(objid, self.objposes[objid]) for objid in next_state.object_states if objid != next_state.robot_id }
[docs] @classmethod def merge(cls, object_observations, next_state, *params, **kwargs): """Merge `object_observations` into a single OOObservation object; object_observation (dict): Maps from objid to ObjectObservation""" return MosOOObservation( { objid: object_observations[objid].pose for objid in object_observations if objid != next_state.object_states[objid].objclass != "robot" } )