C++ Drake控制器声明抽象输入端口获取多体植物接触结果运行段错误
Drake控制器接触结果读取段错误修复方案
核心原因
你遇到的段错误绝大多数情况是输出端口依赖声明遗漏导致的:Drake系统框架采用惰性求值策略,如果你在输出端口的Calc函数中用到了某个输入端口,但没有显式声明该输出端口依赖此输入端口,框架不会提前对该输入端口求值,直接调用Eval读取时就可能拿到未初始化的空指针,触发内存访问错误。
修复步骤
1. 补全输出端口的依赖声明
修改BaseController.cpp中输出端口的声明代码,将接触结果输入端口加入依赖列表:
output_port_index_control_ = this->DeclareVectorOutputPort( "Control Torque", v_dim_, &BaseController<T>::CalcOutputTorque, // 显式指定该输出端口依赖的所有输入端口 {this->input_port_ticket(input_port_index_state_), this->input_port_ticket(input_port_index_contact_result_)}).get_index();
2. 增加接触结果有效性判断
仿真启动初期还未产生接触时,接触结果列表为空,直接索引访问接触对也会触发段错误,建议先判断再访问:
const auto& contact_results = get_input_port_contact_result().template Eval<multibody::ContactResults<T>>(context); // 先判断是否存在接触再访问具体接触项 if (contact_results.num_point_pair_contacts() > 0) { const auto& contact = contact_results.get_point_pair_contact(0); // 后续接触处理逻辑 }
3. 可选:离散系统周期对齐检查
如果你使用的是离散版本的MultibodyPlant或者控制器,要保证两者的更新周期一致,避免出现输入端口求值不同步的问题。
其他排查点
如果上述修改后仍有问题,可以检查:
- 你的控制器中保存的MultibodyPlant指针是否悬空(你当前代码中是构造时传入的builder中的plant引用,指针本身没有问题)
- 输出端口的大小是否和连接的目标端口大小匹配:你当前输出端口大小是
v_dim_,对应plant.get_applied_generalized_force_input_port()的大小,匹配无误 - 注释掉接触相关的代码,确认没有其他逻辑导致段错误,逐步缩小问题范围
内容的提问来源于stack exchange,提问作者Hampton
相关产品推荐
相关产品推荐

