Skip to content

Commit

Permalink
more sapien overloaded functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Lexseal committed Apr 22, 2024
1 parent 159897e commit cd58e01
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 2 deletions.
12 changes: 12 additions & 0 deletions include/mplib/planning_world.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,18 @@ class PlanningWorldTpl {
/// @brief Get the current allowed collision matrix
AllowedCollisionMatrixPtr getAllowedCollisionMatrix() const { return acm_; }

/**
* Set the allowed collision. For more comprehensive API, please get the
* ``AllowedCollisionMatrix`` object and use its methods.
*
* @param name1: name of the first object
* @param name2: name of the second object
*/
void setAllowedCollision(const std::string &name1, const std::string &name2,
bool allowed) {
acm_->setEntry(name1, name2, allowed);
}

/**
* Check if the current state is in collision (with the environment or self
* collision).
Expand Down
107 changes: 105 additions & 2 deletions mplib/sapien_utils/conversion.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import warnings
from typing import Literal, Optional, Sequence

import numpy as np
Expand Down Expand Up @@ -165,9 +166,11 @@ def update_from_simulation(self, *, update_attached_object: bool = True) -> None
)
> 0
):
raise RuntimeError(
warnings.warn(
f"Entity {entity.name} not found in PlanningWorld! "
"The scene might have changed since last update."
"The scene might have changed since last update. "
"Use PlanningWorld.add_object() to add the object.",
stacklevel=2,
)

def check_collision_between(
Expand Down Expand Up @@ -402,6 +405,78 @@ def set_articulation_planned( # type: ignore
articulation = convert_object_name(articulation)
super().set_articulation_planned(articulation, planned)

def has_object(self, obj: Entity | str) -> bool:
"""
Check whether the given non-articulated object exists.
:param obj: the object (or its name) to check
:return: ``True`` if the object exists, ``False`` otherwise.
.. raw:: html
<details>
<summary><a>Overloaded
<code class="docutils literal notranslate">
<span class="pre">PlanningWorld.has_object()</span>
</code>
method</a></summary>
.. automethod:: mplib.PlanningWorld.has_object
:no-index:
.. raw:: html
</details>
"""
if isinstance(obj, Entity):
obj = convert_object_name(obj)
return super().has_object(obj)

def add_object(self, obj: FCLObject | Entity) -> None:
"""
Adds a non-articulated object to the PlanningWorld.
:param obj: the non-articulated object to add
.. raw:: html
<details>
<summary><a>Overloaded
<code class="docutils literal notranslate">
<span class="pre">PlanningWorld.add_object()</span>
</code>
method</a></summary>
.. automethod:: mplib.PlanningWorld.add_object
:no-index:
.. raw:: html
</details>
"""
if isinstance(obj, Entity):
obj = self.convert_physx_component(obj)
if obj is not None:
super().add_object(obj)

def remove_object(self, obj: Entity | str) -> None:
"""
Removes a non-articulated object from the PlanningWorld.
:param obj: the non-articulated object (or its name) to remove
.. raw:: html
<details>
<summary><a>Overloaded
<code class="docutils literal notranslate">
<span class="pre">PlanningWorld.remove_object()</span>
</code>
method</a></summary>
.. automethod:: mplib.PlanningWorld.remove_object
:no-index:
.. raw:: html
</details>
"""
if isinstance(obj, Entity):
obj = convert_object_name(obj)
super().remove_object(obj)

def is_object_attached(self, obj: Entity | str) -> bool: # type: ignore
"""
Check whether the given non-articulated object is attached
Expand Down Expand Up @@ -643,6 +718,34 @@ def attach_mesh( # type: ignore
)
super().attach_mesh(mesh_path, articulation, link, pose, convex=convex)

def set_allowed_collision(
self, obj1: Entity | str, obj2: Entity | str, allowed: bool
) -> None:
"""
Set allowed collision between two objects.
:param obj1: the first object (or its name)
:param obj2: the second object (or its name)
.. raw:: html
<details>
<summary><a>Overloaded
<code class="docutils literal notranslate">
<span class="pre">PlanningWorld.set_allowed_collision()</span>
</code>
method</a></summary>
.. automethod:: mplib.PlanningWorld.set_allowed_collision
:no-index:
.. raw:: html
</details>
"""
if isinstance(obj1, Entity):
obj1 = convert_object_name(obj1)
if isinstance(obj2, Entity):
obj2 = convert_object_name(obj2)
super().set_allowed_collision(obj1, obj2, allowed)


class SapienPlanner(Planner):
def __init__(
Expand Down
3 changes: 3 additions & 0 deletions pybind/pybind_planning_world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ void build_pyplanning_world(py::module &pymp) {

.def("get_allowed_collision_matrix", &PlanningWorld::getAllowedCollisionMatrix,
DOC(mplib, PlanningWorldTpl, getAllowedCollisionMatrix))
.def("set_allowed_collision", &PlanningWorld::setAllowedCollision,
py::arg("name1"), py::arg("name2"), py::arg("allowed"),
DOC(mplib, PlanningWorldTpl, setAllowedCollision))

.def("is_state_colliding", &PlanningWorld::isStateColliding,
DOC(mplib, PlanningWorldTpl, isStateColliding))
Expand Down

0 comments on commit cd58e01

Please sign in to comment.