Learning-and-Intelligent-Systems / predicators

Learning for effective and efficient bilevel planning
MIT License
90 stars 15 forks source link

Issues about Occlusion in Satellites #1692

Closed Jaraxxus-Me closed 2 months ago

Jaraxxus-Me commented 3 months ago

Hi, (sorry for bugging again) For the "Sees" predicate, you calculate the perpendicular distance to determine if an entity may occlude the satellite's sight. As implemented here. However, I think we also need to check the cross-product to additionally make sure the entity lies "between" the satellite and object, e.g., use the following code:

    def _Sees_holds(self, state: State, objects: Sequence[Object]) -> bool:
        sat, obj = objects
        triangle = self._get_fov_geom(state, sat)
        sat_x = state.get(sat, "x")
        sat_y = state.get(sat, "y")
        obj_x = state.get(obj, "x")
        obj_y = state.get(obj, "y")
        # Note: we require only that the center of the object
        # is in the view cone, ignoring the object's radius.
        if not triangle.contains_point(obj_x, obj_y):
            return False
        # Now check if the line of sight is occluded by another entity.
        dist_denom = np.sqrt((sat_x - obj_x)**2 + (sat_y - obj_y)**2)
        for ent in state:
            if ent in (sat, obj):
                continue
            # Compute the projection distance of this entity onto the line
            # segment connecting `sat` and `obj`.
            ent_x = state.get(ent, "x")
            ent_y = state.get(ent, "y")

            # Check if the entity is between the satellite and the object
            dot_product = (ent_x - sat_x) * (obj_x - sat_x) + (ent_y - sat_y) * (obj_y - sat_y)
            if dot_product < 0: # before start
                continue

            if dot_product > dist_denom**2: # after end
                continue

            # Compute perpendicular distance from entity to line
            dist = abs((obj_x - sat_x) * (sat_y - ent_y) - (sat_x - ent_x) * (obj_y - sat_y)) / dist_denom
            if dist < self.radius * 2:
                return False
        return True

Otherwise, there could be some cases (e.g., ent is on the line of sat-obj, but not between them) wrongly ground "Sees". Correct me if I'm wrong, I'm happy to submit a pr for this.

NishanthJKumar commented 2 months ago

i see what you mean. I think in the original satellites environment, we deliberately didn't check for this kind of occlusion. However, it is certainly more reasonable to do something like this. Feel free to make this modification in the new subclass environment you're proposing to make, but leave the original Satellites environment alone so that previous results are unchanged.

Jaraxxus-Me commented 2 months ago

Sure, will submit a PR late this week!