Skip to content

Move from string-based links and joints to id-based logic (using hashes)#734

Draft
rjoomen wants to merge 35 commits into
tesseract-robotics:masterfrom
rjoomen:feature/integer-link-ids
Draft

Move from string-based links and joints to id-based logic (using hashes)#734
rjoomen wants to merge 35 commits into
tesseract-robotics:masterfrom
rjoomen:feature/integer-link-ids

Conversation

@rjoomen

@rjoomen rjoomen commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/JointId in 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()->second is 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.

Comment thread examples/src/glass_upright_ompl_example.cpp

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread command_language/src/utils.cpp Outdated
Comment thread task_composer/test/fix_state_bounds_task_unit.cpp Outdated
Comment thread command_language/test/command_language_utils_unit.cpp Outdated
Comment thread command_language/src/utils.cpp
Comment thread command_language/src/utils.cpp Outdated
Comment thread task_composer/planning/src/nodes/fix_state_collision_task.cpp
Comment thread task_composer/core/include/tesseract/task_composer/test_suite/test_programs.hpp Outdated
Comment thread command_language/test/type_erasure_benchmark.cpp Outdated
Comment thread command_language/test/command_language_unit.cpp Outdated
rjoomen added a commit to rjoomen/tesseract_planning that referenced this pull request Apr 20, 2026
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>
rjoomen added a commit to rjoomen/tesseract_planning that referenced this pull request Apr 20, 2026
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>
rjoomen added a commit to rjoomen/tesseract_planning that referenced this pull request Apr 20, 2026
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>
@rjoomen rjoomen requested a review from Copilot April 20, 2026 06:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread motion_planners/descartes/src/descartes_collision.cpp
Comment thread examples/src/glass_upright_ompl_example.cpp
Comment thread motion_planners/simple/src/simple_motion_planner.cpp
Comment thread command_language/include/tesseract/command_language/utils.h Outdated
rjoomen added a commit to rjoomen/tesseract_planning that referenced this pull request Apr 20, 2026
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>
rjoomen added a commit to rjoomen/tesseract_planning that referenced this pull request Apr 20, 2026
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>
rjoomen added a commit to rjoomen/tesseract_planning that referenced this pull request Apr 20, 2026
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>
rjoomen added a commit to rjoomen/tesseract_planning that referenced this pull request Apr 20, 2026
…_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>
@rjoomen rjoomen requested a review from Copilot April 20, 2026 07:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

  • state is thread_local and is no longer cleared between calls. If calcFwdKin doesn’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 before calcFwdKin(...) (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:1
  • calcFwdKin(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 output LinkIdTransformMap (e.g., thread-local or stack-allocated and cleared) and calling the calcFwdKin(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 checking swp.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.

Comment thread command_language/src/utils.cpp Outdated
Comment thread command_language/src/utils.cpp Outdated
Comment thread command_language/src/utils.cpp
Comment thread command_language/src/utils.cpp Outdated
Comment thread command_language/src/utils.cpp Outdated
Comment thread command_language/test/command_language_utils_unit.cpp
Comment thread command_language/test/command_language_utils_unit.cpp

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

rjoomen added a commit to rjoomen/tesseract_planning that referenced this pull request Apr 25, 2026
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>
rjoomen added a commit to rjoomen/tesseract_planning that referenced this pull request Apr 25, 2026
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>
rjoomen added a commit to rjoomen/tesseract_planning that referenced this pull request Apr 25, 2026
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>
rjoomen and others added 30 commits May 12, 2026 11:29
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants