基于几何信息编写控制器:Drake网格/凸形表面法线获取问询
基于Drake网格/凸形的刚体表面法线计算
完全可以直接通过Drake的原生几何表示(网格/凸形)完成这类几何计算,不需要转换为点云——这种方式性能远优于点云处理,也是Drake几何模块的设计初衷之一。以下是具体实现方法:
一、网格(Mesh)的表面法线获取
Drake的Mesh类原生存储了三角面的拓扑与几何信息,获取法线有两种常用方式:
- 批量获取预计算法线:如果网格是从带法线的格式(如.obj)导入,或Drake已自动计算法线,直接调用
mesh.triangle_normals()即可得到所有三角面的单位法线数组,返回类型为Eigen::Matrix<double, 3, Eigen::Dynamic>,每一列对应一个三角面的法线向量。 - 实时计算单个三角面法线:针对特定三角面,可通过三个顶点坐标叉乘推导:
const auto& vertices = mesh.vertices(); const auto& faces = mesh.triangles(); // 取第i个三角面的三个顶点 Eigen::Vector3d v0 = vertices.col(faces(i, 0)); Eigen::Vector3d v1 = vertices.col(faces(i, 1)); Eigen::Vector3d v2 = vertices.col(faces(i, 2)); // 计算并归一化法线 Eigen::Vector3d normal = (v1 - v0).cross(v2 - v0).normalized();
二、凸形(Convex)的表面法线获取
Drake的Convex以凸多面体为核心表示,表面由平面面组成,获取法线的方式更直接:
- 遍历所有面的法线:调用
convex.faces()获取所有面的集合,每个面实例的normal()方法直接返回该面的单位法线:const Convex& convex = ...; // 你的凸形实例 for (const auto& face : convex.faces()) { const Eigen::Vector3d& face_normal = face.normal(); // 基于法线执行后续计算 } - 基础凸形的法线推导:对于Box、Sphere等原生基本体,可直接通过几何参数推导法线。比如Box的六个面法线固定为±x、±y、±z方向的单位向量。
三、典型几何操作的直接实现
以“获取刚体表面某点的法线”为例,无需转点云:
- 网格场景:用Drake的
Raycast或ComputeSignedDistancePairwiseClosestPoints接口,找到该点所属的三角面,直接复用该面的法线; - 凸形场景:通过点在凸形表面的归属面查询,获取对应面的法线。
Drake的SceneGraph提供的所有几何查询接口,均基于原生几何表示实现,性能和精度都远优于点云转换后的处理。
内容的提问来源于stack exchange,提问作者HoliInn
相关产品推荐
相关产品推荐

