collisionVHACD
Syntax
Description
decomposes a triangulation mesh into convex collision meshes using a voxelized hierarchical
approximate convex decomposition (V-HACD) solver.convexCollMeshes
= collisionVHACD(sourceMesh
)
specifies the solver options of the V-HACD solver.convexCollMeshes
= collisionVHACD(sourceMesh
,options
)
[
returns information about the decomposition. in addition to the decomposed convex collision
meshes, using any combination of input arguments from previous syntaxes.convexCollMeshes
,info
] = collisionVHACD(___)
Examples
Decompose Non-Convex Meshes for Collision Checking
Load an STL file containing a rectangular bin triangulation, and then visualize the bin triangulation.
meshTri = stlread("bin.stl"); trisurf(meshTri) axis equal
Create a collision mesh using the points from the triangulation of the bin, and then visualize the mesh. Note that, when you approximate the bin triangulation as one collision mesh, the collisionMesh
object uses the convex hull of the bin triangulation to approximate the bin. As a result the collision mesh is convex, unlike the non-convex bin triangulation. The collisionMesh
object does this because collision checking is most efficient with convex meshes. However, this convex approximation is not ideal for bins because robots can manipulate bins or objects inside of bins.
meshColl = collisionMesh(meshTri.Points); [~,p] = show(meshColl); view(145,30) % Change view so it is easier to view the inside of bin axis equal hold on
Create a soda can using a collision cylinder, and set the pose such that it sits in the center of the bin. Then, show it in the convex collision mesh.
sodacan = collisionCylinder(0.1,0.4,Pose=trvec2tform([0 0 .3])); show(sodacan);
Set the box to be transparent so that you can see the overlap between the bin and the soda can.
p.FaceAlpha = 0.25;
hold off
Check collision between the soda can and the convex approximation of the bin, and note that they are in collision.
isCollidingConvex = checkCollision(sodacan,meshColl)
isCollidingConvex = 1
To get a better approximation of the bin for collision checking, decompose the original non-convex mesh into multiple convex meshes using voxelized hierarchical approximate convex decomposition (V-HACD).
Use the collisionVHACD
function to decompose the original non-convex triangulation into convex collision meshes. Then, show the decomposed bin with the soda can.
decomposedBin = collisionVHACD(meshTri);
showCollisionArray([decomposedBin {sodacan}]);
view(145,30)
axis equal
Check collision with all the meshes that approximate the bin. Note that the soda can is not in collision with the decomposed non-convex approximation of the bin. If you require a more accurate decomposition of the bin, you can specify custom solver options using the vhacdOptions
object.
isColliding = false(1,length(decomposedBin)); for i = 1:length(decomposedBin) isColliding(i) = checkCollision(sodacan,decomposedBin{i}); end isCollidingAll = all(isColliding)
isCollidingAll = logical
0
Replace Rigid Body Collision Meshes with Decompositions of Visual Meshes
Load the Rethink Robotics Sawyer robot.
robot = loadrobot("rethinkSawyer",DataFormat="row")
robot = rigidBodyTree with properties: NumBodies: 20 Bodies: {1x20 cell} Base: [1x1 rigidBody] BodyNames: {1x20 cell} BaseName: 'base' Gravity: [0 0 0] DataFormat: 'row'
Show the robot with just the visual meshes and show the robot with just the collision meshes. Use a vertical view so the difference between the arms is more clear.
tiledlayout(1,2) sgtitle("Rethink Robotics Sawyer") nexttile show(robot,Visuals="on",Collisions="off"); title("Top Down View") axis auto view(90,90) nexttile show(robot,Visuals="off",Collisions="on"); title("Top Down View") axis auto view(90,90)
Note that each body of the arm is represented by a single convex mesh that does not accurately represent the physical boundaries of the arm. To achieve more accurate collision checking, you must decompose the visual meshes of the robot. The rigid body tree stores the rigid bodies of the arm at indices 9
to 17
.
First, create V-HACD solver options for individual mesh decompositions with the maximum number of convex hulls set to 10
.
opts = vhacdOptions("IndividualMesh",MaxNumConvexHulls=10);
Then for each rigid body:
Get the current rigid body and clear the current collision mesh.
Get the corresponding visual data if there is any.
If there is visual data, use
collisionVHACD
with the custom solver options to decompose the triangulation of the visual data into an array of collision meshes.Add each collision mesh from the array of collision meshes to the rigid body.
for bodyIdxToReplace = 9:17 % 1. Get current body and clear collision mesh currBody = robot.Bodies{bodyIdxToReplace}; clearCollision(currBody); % 2. Get Corresponding visual data vizData = getVisual(robot.Bodies{bodyIdxToReplace}); % 3. If visual data, decompose visual data if ~isempty(vizData) collisionArray = collisionVHACD(vizData(1).Triangulation,opts); % 4. Add each collision mesh to the rigid body for j = 1:numel(collisionArray) addCollision(currBody,collisionArray{j}); end end end
Show the original collision meshes of the robot arm next to the updated collision mesh of the arm.
tiledlayout(1,2); sgtitle("Rethink Robotics Sawyer") nexttile robotOriginal = loadrobot("rethinkSawyer",DataFormat="row"); show(robotOriginal,Visuals="off",Collisions="on"); title("Before Decomposition") axis auto view(90,90) nexttile show(robot,Visuals="off",Collisions="on"); title("After Decomposition") view(90,90) axis auto
Note that in this case the new collision meshes represent the robot arm more accurately.
Input Arguments
sourceMesh
— Triangulation of mesh geometry to decompose
triangulation
object
Triangulation of mesh geometry to decompose, specified as a triangulation
object.
For visualizing triangulations of meshes before decomposition, you can use the
trimesh
or trisurf
function.
options
— V-HACD solver options
vhacdOptions
object
V-HACD solver options, specified as a vhacdOptions
object.
You must set the Type
property of the
vhacdOptions
object to "IndividualMesh"
to specify
custom V-HACD options for the collisionVHACD
function. If the
Type
property is set to "RigidBodyTree"
, then
you can only use the vhacdOptions
object for importing rigid body trees
using the importrobot
function
Output Arguments
convexCollMeshes
— Convex collision meshes
N-element cell array of collisionMesh
objects
Convex collision meshes, returned as an N-element cell array of
collisionMesh
objects.
You can use the showCollisionArray
function to visualize the collision meshes.
info
— Decomposition solution information
structure
Decomposition solution information, returned as a structure containing these fields:
SourceVolume
— Volume of the input source mesh specified by thesourceMesh
argument.CompositeDecompVolume
— Total combined volume of the output convex collision meshes. This total includes the volume of overlapping meshes.RawData
— N-element cell array of mesh vertices used to generate the collision array. N is the total number of collision objects needed to represent the decomposed mesh.
References
[1] Mammou, Khaled, et al. “Voxelized Hierarchical Approximate Convex Decomposition - V-HACD Version 4.” GitHub, October 24, 2022. https://github.com/kmammou/v-hacd.
Version History
Introduced in R2023b
See Also
vhacdOptions
| showCollisionArray
| collisionMesh
| checkCollision
| trisurf
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)