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

调用AddFixedConstraint()触发Segmentation fault错误求助

Drake中AddFixedConstraint()触发Segmentation Fault问题排查

错误现象

调用AddFixedConstraint()时触发段错误,错误日志如下:

[2024-02-19 00:26:09.610] [console] [warning] DRAKE DEPRECATED: Use MultibodyPlantConfig::discrete_contact_approximation instead of MultibodyPlantConfig::discrete_contact_solver. The deprecated code will be removed from Drake on or after 2024-04-01.
HEY
Segmentation fault (core dumped)

其中"HEY"为自定义打印语句,确认错误发生在AddFixedConstraint()调用处。

问题代码

///////////////////////
/// Configure Plant ///
///////////////////////
drake::systems::DiagramBuilder<double> builder;

MultibodyPlantConfig plant_config;
plant_config.time_step = time_step;
plant_config.discrete_contact_solver = "sap";

auto [plant, scene_graph] = AddMultibodyPlant(plant_config, &builder);


////////////////////////
/// SETUP PLANE GROUND ///
////////////////////////
ProximityProperties rigid_proximity_props;
const CoulombFriction<double> surface_friction(1.15, 1.15);
AddContactMaterial({}, {}, surface_friction, &rigid_proximity_props);
rigid_proximity_props.AddProperty(drake::geometry::internal::kHydroGroup, drake::geometry::internal::kRezHint, 1.0);

Box ground{2, 2, 2};
const RigidTransformd X_WG(Eigen::Vector3d{0, 0, -1});
plant.RegisterCollisionGeometry(plant.world_body(), X_WG, ground, "ground_collision", rigid_proximity_props);
IllustrationProperties illustration_props;
illustration_props.AddProperty("phong", "diffuse", Vector4d(0.7, 0.5, 0.4, 0.8));
plant.RegisterVisualGeometry(plant.world_body(), X_WG, ground, "ground_visual", std::move(illustration_props));


/////////////////////////////
/// SETUP DEFORMABLE OBJECT ///
/////////////////////////////
auto owned_deformable_model = std::make_unique<DeformableModel<double>>(&plant);

DeformableBodyConfig<double> deformable_config;
deformable_config.set_youngs_modulus(E);
deformable_config.set_poissons_ratio(nu);
deformable_config.set_mass_density(density);
deformable_config.set_stiffness_damping_coefficient(stiffness_beta);

const std::string deformable_vtk = "{MY WORKSPACE PATH}/src/drake_controller/resource/pipe.vtk";
const double scale = 0.01; // 0.65
auto deformable_mesh = std::make_unique<Mesh>(deformable_vtk, scale);
const double kL = 0.09 * scale;

const RigidTransformd X_WB(drake::Vector3<double>(0.0, 0.0, 0.0));
auto torus_instance = std::make_unique<GeometryInstance>( X_WB, std::move(deformable_mesh), "deformable_object");

/* Minimumly required proximity properties for deformable bodies: A valid Coulomb friction coefficient. */
ProximityProperties deformable_proximity_props;
AddContactMaterial({}, {}, surface_friction, &deformable_proximity_props);
torus_instance->set_proximity_properties(deformable_proximity_props);

const double unused_resolution_hint = 1.0;
auto deformable_body_id = owned_deformable_model->RegisterDeformableBody(std::move(torus_instance), deformable_config, unused_resolution_hint);
DeformableModel<double>* deformable_model = owned_deformable_model.get();

plant.AddPhysicalModel(std::move(owned_deformable_model));

////////////////////////
/// SETUP RIGID OBJECT ///
////////////////////////
Parser parser(&plant);

auto peg_idx = parser.AddModels("{MY WORKSPACE PATH}/src/drake_controller/resource/1mm_cylinder.sdf");
const drake::multibody::RigidBody<double>& peg_body = plant.GetBodyByName("cylinder_body");
const drake::multibody::Frame<double>& peg_frame = plant.GetFrameByName("cylinder_top_center");

RigidTransformd W_X_PEG(Eigen::Vector3d{0,0,0});
plant.SetDefaultFreeBodyPose(peg_body, W_X_PEG);
AddFloatingRpyJoint(&plant, const_cast<drake::multibody::RigidBodyFrame<double>&>(peg_frame.body().body_frame()), peg_idx.at(0));

drake::math::RigidTransform<double> RIGID_X_DEFORMABLE(drake::Vector3<double>(0,0,0.02));
drake::math::RigidTransform<double> RIGID_X_GEOMETRY;
drake::geometry::Cylinder peg_mesh(0.048,0.04);
drake::geometry::Shape* peg_shape = peg_mesh.Clone().get();
std::cout << "HEY" << std::endl;
auto multibody_constraint_id = deformable_model->AddFixedConstraint(deformable_body_id, peg_body, RIGID_X_DEFORMABLE, *peg_shape, RIGID_X_GEOMETRY.SetIdentity());
std::cout << "HEY" << std::endl;

//////////////////////////////////
/// FINALIZE OBJECT REGISTRATION ///
//////////////////////////////////
plant.set_gravity_enabled(peg_idx.at(0), false);
plant.Finalize();

已排查情况

已确认排除Drake文档中AddFixedConstraint()的前4种异常触发条件:

  • 已注册对应ID的可变形体
  • 刚体与可变形体属于同一个MultibodyPlant
  • 使用的Cylinder形状属于支持的类型
  • 调用函数时Plant尚未Finalize

仅未排查第5种情况:没有可变形体顶点位于约束形状内部,导致未添加任何约束

问题分析与解决方案

1. 核心问题:悬空指针导致段错误

代码中peg_mesh.Clone().get()会创建临时std::unique_ptr<Shape>,调用get()获取裸指针后,临时智能指针立即销毁,导致peg_shape成为悬空指针。AddFixedConstraint()访问该指针指向的内存时触发段错误。

修复方式:
直接传递peg_mesh的引用,或保存Clone()的结果到智能指针中:

// 方式1:直接使用Cylinder对象的引用
auto multibody_constraint_id = deformable_model->AddFixedConstraint(
    deformable_body_id, peg_body, RIGID_X_DEFORMABLE, 
    peg_mesh, RIGID_X_GEOMETRY.SetIdentity()
);

// 方式2:保存Clone的结果
auto peg_shape = peg_mesh.Clone();
auto multibody_constraint_id = deformable_model->AddFixedConstraint(
    deformable_body_id, peg_body, RIGID_X_DEFORMABLE, 
    *peg_shape, RIGID_X_GEOMETRY.SetIdentity()
);

2. 验证约束形状与可变形体的位置重叠

检查RIGID_X_DEFORMABLE的变换参数,确保圆柱形状覆盖可变形管道的顶点。如果没有顶点位于约束形状内,会触发第5种异常,需调整变换参数或形状尺寸,保证两者有重叠区域。

3. 移除不必要的const_cast

AddFloatingRpyJoint的参数不应使用const_cast强制转换const Frame,正确添加浮动关节的方式:

plant.AddFloatingRpyJoint(
    "peg_joint", plant.world_body(), 
    peg_body.body_frame(), 
    W_X_PEG.rotation(), W_X_PEG.translation()
);

4. 处理废弃API警告

将plant_config.discrete_contact_solver = "sap";替换为:

plant_config.discrete_contact_approximation = DiscreteContactApproximation::kSap;

避免后续版本的兼容性问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 22:35:54