Problem
Robot.get_manipulator_info() in src/tesseract_robotics/planning/core.py:407-440 silently invents a tcp_frame when none is provided:
if tcp_frame is None:
group = self.env.getKinematicGroup(group_name)
tcp_frame = list(group.getActiveLinkNames())[-1]
In C++, ManipulatorInfo is a plain data struct — tcp_frame is an explicit required parameter in the constructor. The planner is responsible for frame resolution. This Python wrapper does resolution too early, hiding it behind a convenience API.
Issues
- Hides a decision the user should make explicitly — grabbing the last active link is a heuristic that works for serial chains but breaks for branching kinematic trees
- Hardcodes
working_frame="base_link" — another silent assumption
- Caches the guess — once auto-detected for a group, the result is cached and can't be corrected for the same
(group, None, working_frame) key
Proposed fix
Make tcp_frame required (no default None), matching the C++ API's intent. Remove the auto-detect heuristic. Users should know which frame they're targeting.
Problem
Robot.get_manipulator_info()insrc/tesseract_robotics/planning/core.py:407-440silently invents atcp_framewhen none is provided:In C++,
ManipulatorInfois a plain data struct —tcp_frameis an explicit required parameter in the constructor. The planner is responsible for frame resolution. This Python wrapper does resolution too early, hiding it behind a convenience API.Issues
working_frame="base_link"— another silent assumption(group, None, working_frame)keyProposed fix
Make
tcp_framerequired (no defaultNone), matching the C++ API's intent. Remove the auto-detect heuristic. Users should know which frame they're targeting.