You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Expression类型点调用QueryObject.ComputeSignedDistanceToPoint实现避障约束?

问题原因与解决方案

你的报错核心是:QueryObject.ComputeSignedDistanceToPoint() 只支持数值型数组输入,无法处理Drake的符号表达式(Expression)——这个方法是用来做实时数值距离查询的,不是为符号优化设计的。

下面提供两种可行的解决思路:


思路1:手动构造符号距离表达式(无需MultibodyPlant)

如果障碍物是简单几何(球、盒子、圆柱等),可以直接写出点到该几何的符号距离公式,再作为约束加入MathematicalProgram。

示例:球型障碍物

import numpy as np
from pydrake.solvers import MathematicalProgram

prog = MathematicalProgram()
# 定义待优化的点变量
x = prog.NewContinuousVariables(3, "x")

# 障碍物参数:球心(0,0,0),半径1.0
cx, cy, cz, obstacle_radius = 0.0, 0.0, 0.0, 1.0
desired_distance = 0.5

# 计算点到球的符号距离表达式
distance_expr = np.sqrt((x[0]-cx)**2 + (x[1]-cy)**2 + (x[2]-cz)**2) - obstacle_radius
# 添加避障约束
prog.AddConstraint(distance_expr >= desired_distance)

复杂几何:用Drake的SignedDistanceFunction生成表达式

如果障碍物是复杂几何,可借助Drake的SignedDistanceFunction自动生成符号距离表达式:

from pydrake.geometry import GeometryInstance, Box, SignedDistanceFunction
from pydrake.math import RigidTransform
from pydrake.symbolic import Variable
from pydrake.solvers import MathematicalProgram

prog = MathematicalProgram()
# 定义待优化的点变量
p_WQ = np.array([Variable("x"), Variable("y"), Variable("z")])

# 创建障碍物几何(以盒子为例)
obstacle_geo = GeometryInstance(
    RigidTransform.Identity(),  # 障碍物在世界坐标系的位姿
    Box(1.0, 1.0, 1.0),
    "obstacle"
)

# 生成符号距离函数
sdf = SignedDistanceFunction(
    geometry=obstacle_geo,
    X_WG=RigidTransform.Identity(),
    p_WQ=p_WQ
)
distance_expr = sdf.evaluator()

# 添加避障约束
desired_distance = 0.5
prog.AddConstraint(distance_expr >= desired_distance)

思路2:改用MultibodyPlant集成场景(推荐复杂场景)

如果你的场景涉及多个运动物体,或者需要自动处理大量几何的距离计算,推荐按照你之前了解的方式,将所有元素集成到MultibodyPlant中,利用Drake提供的DistanceConstraint直接添加避障约束。

示例代码

from pydrake.multibody.plant import MultibodyPlant
from pydrake.geometry import SceneGraph, GeometryInstance, Box
from pydrake.math import RigidTransform
from pydrake.solvers import MathematicalProgram
from pydrake.multibody.inverse_kinematics import DistanceConstraint

# 初始化MultibodyPlant和SceneGraph
plant = MultibodyPlant(time_step=0.0)
scene_graph = SceneGraph()
plant.RegisterAsSourceForSceneGraph(scene_graph)

# 添加锚定障碍物到SceneGraph
source_id = scene_graph.RegisterSource("obstacle_source")
obstacle_geo = GeometryInstance(
    RigidTransform([1.0, 0.0, 0.0]),  # 障碍物在世界坐标系的位置
    Box(0.5, 0.5, 0.5),
    "obstacle"
)
obstacle_id = scene_graph.RegisterAnchoredGeometry(source_id, obstacle_geo)

# 添加一个虚拟刚体,用来承载待优化的点
point_body = plant.AddRigidBody("point_body", mass=0.0)
point_frame = point_body.AddFrame("point_frame")
plant.Finalize()

# 构建优化问题
prog = MathematicalProgram()
context = plant.CreateDefaultContext()
# 定义刚体位姿为优化变量
q = prog.NewContinuousVariables(plant.num_positions(), "q")
prog.SetDecisionVariableValueInContext(q, context, plant.GetPositions(context))

# 添加避障约束:点到障碍物的距离不小于desired_distance
desired_distance = 0.5
constraint = DistanceConstraint(
    plant=plant,
    frameB=point_frame,
    geometry_id=obstacle_id,
    minimum_distance=desired_distance,
    scene_graph=scene_graph,
    context=context
)
prog.AddConstraint(constraint, q)

内容的提问来源于stack exchange,提问作者Rufus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 05:27:03