Move from string-based links and joints to id-based logic (using hashes)#734
Move from string-based links and joints to id-based logic (using hashes)#734rjoomen wants to merge 35 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR migrates motion-planning and command-language code from string-based link/joint identification to id-based logic (e.g., LinkId, JointId), enabling hash/id-driven lookups across kinematics, collision checking, planners, and examples.
Changes:
- Replace link/joint name strings with
LinkId/JointIdin manipulator info, collision configuration, FK transform maps, and waypoint seeds. - Update command-language waypoint models + utilities to store/operate on joint IDs and adjust cereal serialization accordingly.
- Update planners/tests/examples to the new id-based APIs, including active collision object configuration and FK transform handling.
Reviewed changes
Copilot reviewed 85 out of 85 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| time_parameterization/totg/test/time_optimal_trajectory_generation_tests.cpp | Update ManipulatorInfo frames to LinkId. |
| time_parameterization/ruckig/test/ruckig_trajectory_smoothing_tests.cpp | Update ManipulatorInfo frames to LinkId. |
| time_parameterization/kdl/test/constant_tcp_speed_parameterization_tests.cpp | Update ManipulatorInfo frames to LinkId. |
| time_parameterization/kdl/src/constant_tcp_speed_parameterization.cpp | Switch KDL FK transform map + scene graph parsing to id/name accessors. |
| time_parameterization/isp/test/iterative_spline_tests.cpp | Update ManipulatorInfo frames to LinkId. |
| task_composer/test/tesseract_task_composer_planning_unit.cpp | Use LinkId frames and seed JointState via joint IDs. |
| task_composer/test/fix_state_bounds_task_unit.cpp | Construct ManipulatorInfo using LinkId frames. |
| task_composer/planning/src/nodes/format_as_result_task.cpp | Populate StateWaypoint using joint IDs. |
| task_composer/planning/src/nodes/format_as_input_task.cpp | Seed/format joint waypoints using joint IDs. |
| task_composer/planning/src/nodes/fix_state_collision_task.cpp | Convert collision checking to active link IDs + id-based FK state. |
| task_composer/planning/src/nodes/discrete_contact_check_task.cpp | Use active link IDs for discrete contact checks. |
| task_composer/planning/src/nodes/continuous_contact_check_task.cpp | Use active link IDs for continuous contact checks. |
| task_composer/core/include/tesseract/task_composer/test_suite/test_programs.hpp | Construct ManipulatorInfo using LinkId frames in test programs. |
| motion_planners/trajopt_ifopt/src/profile/trajopt_ifopt_default_move_profile.cpp | Build joint waypoints from state waypoints via joint IDs. |
| motion_planners/trajopt/test/trajopt_planner_tests.cpp | Update tests to use LinkId working/tcp frames. |
| motion_planners/trajopt/src/trajopt_utils.cpp | Update TrajOpt term-info utilities to accept LinkId parameters. |
| motion_planners/trajopt/src/profile/trajopt_default_move_profile.cpp | Update active-link checks + fixed joint waypoint creation to joint IDs. |
| motion_planners/trajopt/include/tesseract/motion_planners/trajopt/trajopt_utils.h | Update TrajOpt utility APIs to use LinkId. |
| motion_planners/simple/test/simple_planner_test_utils.hpp | Update ManipulatorInfo frames to LinkId. |
| motion_planners/simple/test/simple_planner_lvs_move_unit.cpp | Build explicit JointState seeds using JointId. |
| motion_planners/simple/test/simple_planner_lvs_assign_no_ik_move_unit.cpp | Build explicit JointState seeds using JointId. |
| motion_planners/simple/test/simple_planner_lvs_assign_move_unit.cpp | Build explicit JointState seeds using JointId. |
| motion_planners/simple/test/simple_planner_fixed_size_move_unit.cpp | Build explicit JointState seeds using JointId. |
| motion_planners/simple/test/simple_planner_fixed_size_assign_move_unit.cpp | Build explicit JointState seeds using JointId. |
| motion_planners/simple/src/simple_motion_planner.cpp | Format results as input using joint IDs; validate joint order via joint IDs. |
| motion_planners/simple/src/profile/simple_planner_lvs_assign_no_ik_move_profile.cpp | Query current joint values via joint IDs. |
| motion_planners/simple/src/profile/simple_planner_lvs_assign_move_profile.cpp | Query current joint values via joint IDs. |
| motion_planners/simple/src/profile/simple_planner_fixed_size_assign_no_ik_move_profile.cpp | Query current joint values via joint IDs. |
| motion_planners/simple/src/profile/simple_planner_fixed_size_assign_move_profile.cpp | Query current joint values via joint IDs. |
| motion_planners/simple/src/interpolation.cpp | Replace string frame checks and FK caches with LinkId/LinkIdTransformMap. |
| motion_planners/simple/include/tesseract/motion_planners/simple/interpolation.h | Change instruction-info structs to store LinkId frames. |
| motion_planners/ompl/test/ompl_planner_tests.cpp | Use LinkId link/joint fields and manipulator frames in tests. |
| motion_planners/ompl/src/utils.cpp | Set collision transforms in bulk using id-based FK result map. |
| motion_planners/ompl/src/state_collision_validator.cpp | Use active link IDs + id-based FK transform map for validity checks. |
| motion_planners/ompl/src/profile/ompl_real_vector_move_profile.cpp | Use joint IDs for joint-format checking and active link IDs for collision. |
| motion_planners/ompl/src/continuous_motion_validator.cpp | Use active link IDs + id-based FK transform maps for motion validation. |
| motion_planners/ompl/src/collision_cost_objective.cpp | Use active link IDs + id-based FK transform map for cost evaluation. |
| motion_planners/ompl/include/tesseract/motion_planners/ompl/state_collision_validator.h | Store active link IDs instead of names. |
| motion_planners/ompl/include/tesseract/motion_planners/ompl/continuous_motion_validator.h | Store active link IDs instead of names. |
| motion_planners/ompl/include/tesseract/motion_planners/ompl/collision_cost_objective.h | Store active link IDs instead of names. |
| motion_planners/examples/raster_example.cpp | Update ManipulatorInfo frames to LinkId. |
| motion_planners/examples/freespace_example.cpp | Update ManipulatorInfo frames to LinkId. |
| motion_planners/examples/chain_example.cpp | Update ManipulatorInfo frames to LinkId. |
| motion_planners/descartes/test/descartes_planner_tests.cpp | Update ManipulatorInfo frames to LinkId. |
| motion_planners/descartes/src/descartes_collision.cpp | Use LinkIdTransformMap and id-based FK results for collision checks. |
| motion_planners/descartes/include/tesseract/motion_planners/descartes/impl/profile/descartes_default_move_profile.hpp | Validate joint format via joint IDs; pass frame names from LinkId. |
| motion_planners/descartes/include/tesseract/motion_planners/descartes/impl/descartes_robot_sampler.hpp | Construct IK inputs via LinkId; use joint IDs + id-based FK cache. |
| motion_planners/descartes/include/tesseract/motion_planners/descartes/impl/descartes_collision_edge_evaluator.hpp | Use active link IDs and id-based collision margin access. |
| motion_planners/descartes/include/tesseract/motion_planners/descartes/descartes_collision_edge_evaluator.h | Store active link IDs (comment needs update). |
| motion_planners/descartes/include/tesseract/motion_planners/descartes/descartes_collision.h | Switch FK cache type and active link storage to id-based types. |
| motion_planners/core/src/utils.cpp | Switch toolpath pose computation + contact-check program plumbing to joint/link IDs. |
| motion_planners/core/include/tesseract/motion_planners/robot_config.h | Use LinkIdTransformMap and LinkId lookups for FK-derived poses. |
| examples/src/scene_graph_example.cpp | Update joint parent/child fields to use LinkId. |
| examples/src/puzzle_piece_example.cpp | Update ManipulatorInfo frames to LinkId. |
| examples/src/puzzle_piece_auxillary_axes_example.cpp | Update ManipulatorInfo frames to LinkId. |
| examples/src/pick_and_place_example.cpp | Use LinkId for joint parent/child and for ManipulatorInfo frames. |
| examples/src/online_planning_example.cpp | Use LinkId FK lookup for tool pose; set environment state via joint-name accessor. |
| examples/src/glass_upright_ompl_example.cpp | Update FK usage to id-based map (currently extracts pose incorrectly). |
| examples/src/glass_upright_example.cpp | Use LinkId for joint parent/child and ManipulatorInfo frames. |
| examples/src/freespace_ompl_example.cpp | Use LinkId for joint parent/child and ManipulatorInfo frames. |
| examples/src/freespace_hybrid_example.cpp | Use LinkId for joint parent/child and ManipulatorInfo frames. |
| examples/src/car_seat_example.cpp | Use LinkId for joint parent/child, transforms, and ManipulatorInfo frames. |
| examples/src/basic_cartesian_example.cpp | Use LinkId for joint parent/child and ManipulatorInfo frames. |
| command_language/test/type_erasure_benchmark.cpp | Construct ManipulatorInfo using LinkId. |
| command_language/test/command_language_utils_unit.cpp | Update tests to use LinkId and build seed joint IDs. |
| command_language/test/command_language_unit.cpp | Construct ManipulatorInfo using LinkId. |
| command_language/test/command_language_test_program.hpp | Build seed joint IDs in test program generation. |
| command_language/src/utils.cpp | Add joint-ID utilities and migrate waypoint joint extraction/formatting. |
| command_language/src/state_waypoint.cpp | Store joint IDs internally; derive names on demand; add joint-id accessors. |
| command_language/src/poly/state_waypoint_poly.cpp | Expose joint-id accessors; return names by value. |
| command_language/src/poly/joint_waypoint_poly.cpp | Expose joint-id accessors; return names by value. |
| command_language/src/poly/cartesian_waypoint_poly.cpp | Treat cartesian seed validity as joint-id based. |
| command_language/src/joint_waypoint.cpp | Store joint IDs internally; derive names on demand; add joint-id accessors. |
| command_language/include/tesseract/command_language/utils.h | Change joint-name extraction to return by value; add joint-id APIs. |
| command_language/include/tesseract/command_language/test_suite/state_waypoint_poly_unit.hpp | Update tests to use setters instead of mutating name refs. |
| command_language/include/tesseract/command_language/test_suite/move_instruction_poly_unit.hpp | Construct ManipulatorInfo using LinkId. |
| command_language/include/tesseract/command_language/test_suite/joint_waypoint_poly_unit.hpp | Update tests to use setters instead of mutating name refs. |
| command_language/include/tesseract/command_language/test_suite/cartesian_waypoint_poly_unit.hpp | Build cartesian seed state using joint IDs. |
| command_language/include/tesseract/command_language/state_waypoint.h | Add joint-id storage/accessors + cereal load/save friend declarations. |
| command_language/include/tesseract/command_language/poly/state_waypoint_poly.h | Extend interface to include joint IDs; return names by value. |
| command_language/include/tesseract/command_language/poly/joint_waypoint_poly.h | Extend interface to include joint IDs; return names by value. |
| command_language/include/tesseract/command_language/joint_waypoint.h | Add joint-id storage/accessors + cereal load/save friend declarations. |
| command_language/include/tesseract/command_language/cereal_serialization.h | Switch Joint/State waypoint serialization to non-member load/save for id-backed storage. |
| command_language/POLY_TYPE_DESIGN.md | New documentation describing the poly/type-erasure architecture. |
| CLAUDE.md | New repository guidance file (architecture + patterns overview). |
Comments suppressed due to low confidence (1)
examples/src/glass_upright_ompl_example.cpp:199
- Same issue here:
transforms.begin()->secondis not guaranteed to be the TCP (or any specific) link transform, so the constraint may compute an angle for the wrong frame. Select the intended link explicitly from the FK results (e.g., by keying on the tool link id/name) instead of taking the first element.
auto transforms = fwd_kin_->calcFwdKin(x);
const Eigen::Isometry3d& pose = transforms.begin()->second;
Eigen::Vector3d z_axis = pose.matrix().col(2).template head<3>().normalized();
out[0] = std::atan2(z_axis.cross(normal_).norm(), z_axis.dot(normal_));
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 87 out of 87 changed files in this pull request and generated 10 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Reason: flagged by Copilot PR review on tesseract-robotics#734; prevents -Wunused-using-declaration noise when warnings are treated as errors. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The JointId-based getJointPosition / formatJointPosition overloads still threw "Joint name ..." on mismatch, making failures misleading when the caller passed IDs. String-name overloads keep their original wording. Reason: flagged by Copilot PR review on tesseract-robotics#734. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The id-migration switched from a reused thread-local LinkIdTransformMap and calcFwdKin(out_map, joints) to "auto state = calcFwdKin(start_pos)", which allocates a new map on every call. stateInCollision can run on a hot path during collision fixing, so restore the previous pattern. Also add <cstdint> in motion_planners/robot_config.h: the enum now uses std::uint8_t and was relying on transitive includes. Reason: flagged by Copilot PR review on tesseract-robotics#734. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 83 out of 83 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (2)
examples/src/glass_upright_ompl_example.cpp:205
- This collision constraint constructs a LinkId from tcp_link_ on every evaluation. Since LinkId creation likely hashes the string, consider storing a tesseract::common::LinkId member (initialized once in the ctor) and using it directly in transforms.at(...) to reduce per-call overhead in OMPL constraints.
GlassUprightConstraint(const Eigen::Vector3d& normal,
tesseract::kinematics::ForwardKinematics::Ptr fwd_kin,
std::string tcp_link)
: ompl::base::Constraint(fwd_kin->numJoints(), 1)
, normal_(normal.normalized())
, fwd_kin_(std::move(fwd_kin))
, tcp_link_(std::move(tcp_link))
{
}
~GlassUprightConstraint() override = default;
void function(const Eigen::Ref<const Eigen::VectorXd>& x, Eigen::Ref<Eigen::VectorXd> out) const override
{
auto transforms = fwd_kin_->calcFwdKin(x);
const Eigen::Isometry3d& pose = transforms.at(tesseract::common::LinkId(tcp_link_));
Eigen::Vector3d z_axis = pose.matrix().col(2).template head<3>().normalized();
out[0] = std::atan2(z_axis.cross(normal_).norm(), z_axis.dot(normal_));
}
motion_planners/core/include/tesseract/motion_planners/robot_config.h:35
- This header now uses tesseract::common::LinkId and tesseract::common::LinkIdTransformMap, but it doesn't include the header that defines them. Please add a direct include (e.g., <tesseract/common/types.h>) so robot_config.h is self-contained and doesn't rely on transitive includes.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
validate() and distance() receive transforms_cache as a reusable buffer (the sampler holds a thread_local LinkIdTransformMap that loops over every IK solution). Assigning transforms_cache = manip_->calcFwdKin(pos) builds a fresh map inside calcFwdKin on every call and move-assigns it in, throwing away the thread_local's reserved buckets. Use the calcFwdKin(out_map, joints) overload so the existing storage is reused. Reason: flagged by Copilot PR review on tesseract-robotics#734 (descartes_collision.cpp:66). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Store tcp_link_ as a LinkId member so its hash is computed once in the constructor rather than rebuilt on every constraint evaluation inside the OMPL sampler loop. Note: this file isn't wired into examples/CMakeLists.txt, so the change is compile-untested; it is syntactically consistent with the rest of the id migration. Reason: flagged by Copilot PR review on tesseract-robotics#734. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The surrounding logic already queries manip->getJointIds() for format checking and for start_state.getJointValues(); building the JointState seed from getJointNames() was the odd one out and forced a redundant name->id lookup inside the JointState constructor. Reason: flagged by Copilot PR review on tesseract-robotics#734. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…_utils getJointNames' @param said "extract the joint position from", which was a copy-paste from getJointPosition — corrected to "joint names". planner_utils.h exposes common::LinkId in isValidState's signature but was relying on a transitive include for the definition; include <tesseract/common/types.h> directly. Reason: flagged by Copilot PR review on tesseract-robotics#734. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 83 out of 83 changed files in this pull request and generated 7 comments.
Comments suppressed due to low confidence (4)
task_composer/planning/src/nodes/fix_state_collision_task.cpp:1
stateisthread_localand is no longer cleared between calls. IfcalcFwdKindoesn’t overwrite all entries every time (or if the active links set changes), stale transforms can persist and be consumed by collision checking, potentially producing incorrect results without throwing. Clear the map beforecalcFwdKin(...)(or switch to an API that returns a fresh transform map per call) to avoid reusing stale data.
task_composer/planning/src/nodes/fix_state_collision_task.cpp:1calcFwdKin(start_pos)returning a transform map by value may allocate and re-hash on each invocation. Since this codepath can run in iterative collision-fixing loops, consider reusing an outputLinkIdTransformMap(e.g., thread-local or stack-allocated and cleared) and calling thecalcFwdKin(out, ...)overload if available to reduce per-iteration allocations.
motion_planners/simple/test/simple_planner_lvs_move_unit.cpp:1- This manual loop for converting joint names to
JointIds is repeated across multiple simple planner tests in this PR. Consider using a shared helper (e.g.,tesseract::common::toIds<tesseract::common::JointId>(joint_names_)) to reduce duplication and keep the tests consistent.
motion_planners/core/src/utils.cpp:1 StateWaypointPoly::getNames()now returns by value, so this assert creates an unnecessary allocation/copy just to get a size. Prefer checkingswp.getJointIds().size()(or the stored position size invariants) to avoid extra work in a hot utility function.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 74 out of 74 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Reason: flagged by Copilot PR review on tesseract-robotics#734; prevents -Wunused-using-declaration noise when warnings are treated as errors. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The JointId-based getJointPosition / formatJointPosition overloads still threw "Joint name ..." on mismatch, making failures misleading when the caller passed IDs. String-name overloads keep their original wording. Reason: flagged by Copilot PR review on tesseract-robotics#734. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The id-migration switched from a reused thread-local LinkIdTransformMap and calcFwdKin(out_map, joints) to "auto state = calcFwdKin(start_pos)", which allocates a new map on every call. stateInCollision can run on a hot path during collision fixing, so restore the previous pattern. Also add <cstdint> in motion_planners/robot_config.h: the enum now uses std::uint8_t and was relying on transitive includes. Reason: flagged by Copilot PR review on tesseract-robotics#734. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Convert motion planner and task composer callers from string-based setNames/getNames to JointId-based setJointIds/getJointIds when copying between waypoints (no external string source). Callers that receive strings from external APIs (joint groups, user input) remain unchanged. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Change stored active link members from vector<string> to vector<LinkId> and use getActiveLinkIds()/setActiveCollisionObjects(LinkId) throughout: - Descartes: active_link_names_ -> active_link_ids_ - OMPL StateCollisionValidator: links_ -> link_ids_ - OMPL ContinuousMotionValidator: links_ -> link_ids_ - OMPL CollisionCostObjective: links_ -> link_ids_ - OMPL real vector move profile: 4 call sites updated - Core utils: convert getActiveCollisionObjects() to LinkId set for addInterpolatedCollisionResults (12 call sites) TrajOpt motion planner not migrated because active_links is passed to the TrajOptMoveProfile::create() virtual interface which still takes vector<string>; that requires a profile API change. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace getActiveLinkNames() with getActiveLinkIds() in the 3 contact check task nodes so setActiveCollisionObjects() uses LinkId directly, avoiding string lookups at collision check time. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…h JointIds Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…kId fields ManipulatorInfo.working_frame and .tcp_frame are now LinkId instead of std::string. Update all usages across motion planners, profiles, time parameterization, task composer, examples, and tests: - Change struct fields in JointGroupInstructionInfo and KinematicGroupInstructionInfo from std::string to LinkId - Use .name() where functions still expect std::string (parseSceneGraph, calcPose, createAvoidSingularityTermInfo, std::find on active_links, DescartesRobotSampler constructor) - Use .isValid() instead of .empty() for LinkId validation - Remove redundant LinkId::fromName() on fields that are already LinkId - Update all ManipulatorInfo constructor calls to use LinkId::fromName() - Pass LinkId directly to KinGroupIKInput, CartPosConstraint, and createCartesianWaypointTermInfo which now accept LinkId Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
command_language: add checkJointPositionFormat overload taking JointId vector, used by Descartes and OMPL planners. motion_planners: change calcPose and createAvoidSingularityTermInfo to take LinkId instead of string; pass ManipulatorInfo LinkId fields directly instead of calling .name(); use getActiveLinkIds/getJointIds in Descartes collision evaluator, OMPL profile, and simple planner; use getGroupJointIds in assignCurrentStateAsSeed. time_parameterization: use LinkId in constant TCP speed parameterization. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nst-ref for string vectors Take Eigen::VectorXd by value and std::move into members in JointWaypoint and StateWaypoint constructors. Change string vector params from by-value to const-ref since they are iterated, not stored. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…target_frame Update CartesianWaypointTermInfo field names to match upstream TermInfo API changes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use tesseract::common::toIds<JointId> / toNames at the manual loop sites in JointWaypoint, StateWaypoint, the cereal serializer, and a handful of unit / test-program sites now that the helpers exist in tesseract::common. - JointWaypoint / StateWaypoint: move joint_ids_ into the member initializer via toIds<JointId>(names); setNames becomes a single toIds<JointId> assignment; getNames becomes a single toNames call. Drops the NOLINT(modernize-pass-by-value) comment since the param is only used through toIds. - Cereal save / load for JointWaypoint and StateWaypoint uses toNames / toIds instead of manual reserve + emplace_back loops. - command_language_utils_unit.cpp and command_language_test_program.hpp seed-state setup sites use seed_state.joint_ids = toIds<JointId>(joint_names); in place of manual reserve + push_back(JointId::fromName(...)) loops.
…n ID overloads Add ID-taking overloads of formatJointPosition and getJointPosition in command_language::utils so callers can skip the string round-trip, and have the existing string overloads delegate via toIds<JointId>. The new overloads rewrite the reorder loop to work directly on std::vector<JointId>, which compares id-value for equality and removes the seed.joint_ids = toIds(joint_names) round-trip that previously closed out the string-based implementation. - utils.h: declare the new ID overloads alongside the existing string ones plus a matching = delete template guard to prevent implicit WaypointPoly conversions. - utils.cpp: implement getJointPosition(vector<JointId>, WaypointPoly) mirroring the existing string-based one, and rewrite formatJointPosition(vector<JointId>, WaypointPoly) end-to-end on ID vectors; the string overload collapses to a one-line delegate. - command_language_utils_unit.cpp: add formatJointPositionByIdTests exercising the ID-taking formatJointPosition path, and disambiguate brace-enclosed initializer lists at the remaining call sites by explicitly constructing std::vector<std::string> / std::vector<JointId> now that both overloads resolve the literal. motion_planners/core/src/utils.cpp: switch formatProgramHelper / formatProgram to cache std::vector<JointId> via env.getGroupJointIds and call the new formatJointPosition ID overload directly, so the string detour is gone on the hot planner-program formatting path.
…to LinkId tesseract::common dropped LinkId::fromName() / JointId::fromName() and ManipulatorInfo now takes LinkId directly. Migrate the remaining tesseract_planning call sites and convert a couple of planner APIs that still accepted string link names. motion_planners: - core/robot_config.h: getRobotConfig now takes LinkId for base_link and tcp_frame; the RobotConfig enum gets an explicit std::uint8_t underlying type. - core/planner_utils.h: signature updates to take LinkId / JointId. - descartes: collision-edge-evaluator, robot-sampler, and default move-profile signatures migrate to LinkId (header + hpp). - test suites (descartes, ompl, simple, trajopt): LinkId::fromName / JointId::fromName -> ctor or implicit std::string -> NameId conversion, and ManipulatorInfo ctors lose the explicit LinkId wrapping. command_language: - test_suite/cartesian_waypoint_poly_unit.hpp and test_suite/move_instruction_poly_unit.hpp: implicit string -> LinkId / JointId at ManipulatorInfo and seed_state.joint_ids construction sites. - command_language_unit.cpp, type_erasure_benchmark.cpp: implicit string -> LinkId at ManipulatorInfo sites. - command_language_utils_unit.cpp: remaining tests that used std::vector<std::string> joint_names only to populate a std::vector<JointId> change the declaration to std::vector<JointId> directly and drop the reserve + push_back loop in favor of a plain assignment (seed_state.joint_ids = joint_names). task_composer + time_parameterization + examples: remaining LinkId::fromName / JointId::fromName -> ctor or implicit conversion at call sites.
calcFwdKin now returns a LinkIdTransformMap; transforms.begin()->second picks an arbitrary link in hash order rather than the TCP, so the upright constraint could evaluate the wrong pose. Look up tcp_link_ explicitly, and plumb a tcp link parameter through GlassUprightConstraint which previously had no way to identify its tip. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reason: flagged by Copilot PR review on tesseract-robotics#734; prevents -Wunused-using-declaration noise when warnings are treated as errors. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The JointId-based getJointPosition / formatJointPosition overloads still threw "Joint name ..." on mismatch, making failures misleading when the caller passed IDs. String-name overloads keep their original wording. Reason: flagged by Copilot PR review on tesseract-robotics#734. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The id-migration switched from a reused thread-local LinkIdTransformMap and calcFwdKin(out_map, joints) to "auto state = calcFwdKin(start_pos)", which allocates a new map on every call. stateInCollision can run on a hot path during collision fixing, so restore the previous pattern. Also add <cstdint> in motion_planners/robot_config.h: the enum now uses std::uint8_t and was relying on transitive includes. Reason: flagged by Copilot PR review on tesseract-robotics#734. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
validate() and distance() receive transforms_cache as a reusable buffer (the sampler holds a thread_local LinkIdTransformMap that loops over every IK solution). Assigning transforms_cache = manip_->calcFwdKin(pos) builds a fresh map inside calcFwdKin on every call and move-assigns it in, throwing away the thread_local's reserved buckets. Use the calcFwdKin(out_map, joints) overload so the existing storage is reused. Reason: flagged by Copilot PR review on tesseract-robotics#734 (descartes_collision.cpp:66). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Store tcp_link_ as a LinkId member so its hash is computed once in the constructor rather than rebuilt on every constraint evaluation inside the OMPL sampler loop. Note: this file isn't wired into examples/CMakeLists.txt, so the change is compile-untested; it is syntactically consistent with the rest of the id migration. Reason: flagged by Copilot PR review on tesseract-robotics#734. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The surrounding logic already queries manip->getJointIds() for format checking and for start_state.getJointValues(); building the JointState seed from getJointNames() was the odd one out and forced a redundant name->id lookup inside the JointState constructor. Reason: flagged by Copilot PR review on tesseract-robotics#734. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…_utils getJointNames' @param said "extract the joint position from", which was a copy-paste from getJointPosition — corrected to "joint names". planner_utils.h exposes common::LinkId in isValidState's signature but was relying on a transitive include for the definition; include <tesseract/common/types.h> directly. Reason: flagged by Copilot PR review on tesseract-robotics#734. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ive_links Drop explicit `tesseract::common::LinkId(...)` wrappers at example and test call sites that already relied on implicit string conversion, and flip the TrajOpt waypoint-profile `create()` parameter from `std::vector<std::string>` to `std::vector<LinkId>`, switching the planner's call site to `getActiveLinkIds()`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…PLICIT in production libs Mirror the tesseract repo split of TESSERACT_COMPILE_DEFINITIONS into _PUBLIC / _PRIVATE and apply TESSERACT_NAMEID_NO_IMPLICIT PRIVATE on each production library. Tests and examples keep the implicit string→NameId conversion. Migrate the pathways the compiler now flagged: - JointWaypoint / StateWaypoint invert their ctor overloads: the vector<JointId> form is now the non-template preferred path, while vector<string> becomes a SFINAE template that hashes via toIds. - WaypointPoly tests use toIds<JointId>(names) on assignment paths and drop now-unnecessary JointId(...) wrappers. - ConstantTCPSpeedParameterization passes LinkIds directly to parseSceneGraph instead of round-tripping through .name(). Drive-by: simple-planner test fixtures replace the manual reserve+loop+position-assign with the JointState(names, position) constructor. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Requires tesseract-robotics/tesseract#1274