Skip to content

[Bug]: motion_planner.py doesn't fill good_solution from IK correctly when successful IK instances are insufficient #717

Description

@shundroid

Prerequisites

  • I have searched existing issues and discussions and could not find a duplicate.
  • I have read the relevant section of the documentation.
  • I can reproduce this on the latest main (or the most recent release).

Bug summary

The code below seems intended to fill in the good solution when successful IK instances are insufficient. However, the trailing [:, :] turns seed_config[~ik_result.success] into a read, which returns a copy rather than a view, so the seed config is not updated.

if success_count < num_seeds:
good_solution = seed_config[ik_result.success][0:1, :].clone()
seed_config[~ik_result.success][:, :] = good_solution

Note that other parts of the code write to the ~success indexed view correctly:

# make failed paths false:
interpolated_valid[~path_result.success] = False

Steps to reproduce

Here is the effect of the extra `[:, :]`:


import torch

sol = torch.arange(1 * 4 * 7, dtype=torch.float32).view(1, 4, 7)   # (1, num_seeds, dof)
suc = torch.tensor([[True, False, True, False]])                    # (1, num_seeds)

buggy = sol.clone()
good = buggy[suc][0:1, :].clone()
buggy[~suc][:, :] = good          # current code
assert torch.equal(buggy, sol)    # passes -> nothing was written

fixed = sol.clone()
good = fixed[suc][0:1, :].clone()
fixed[~suc] = good                # single-step __setitem__
assert not torch.equal(fixed, sol)
assert torch.equal(fixed[0, 1], good[0]) and torch.equal(fixed[0, 3], good[0])
assert torch.equal(fixed[0, 0], sol[0, 0])   # successful seeds untouched

Expected behavior

When fewer than num_seeds IK solutions succeed, the failed entries of seed_config should be overwritten with a copy of a successful solution, so that trajopt_solver.solve_pose() receives num_seeds valid seeds.

Actual behavior / error output

`seed_config` is left unchanged and no error is raised. `seed_config` is returned unchanged and no error is raised, so failed IK solutions are passed to TrajOpt as seeds. There is no traceback.

`a[mask] = v` compiles to a single `a.__setitem__(mask, v)` and writes to `a`. The trailing index makes `a[mask][:, :] = v` evaluate `a[mask]` as a read first; boolean mask indexing returns a copy, so the assignment updates that temporary and it is discarded.

Impact: TrajOpt optimizes all seeds in parallel and returns the best one, so the resulting trajectory is still valid. However, the effective seed count is silently reduced whenever IK partially fails. The degradation is largest on exactly the hard problems where seed diversity matters most, and it is invisible because no error surfaces.

cuRobo version + commit SHA

main @ 8e734f3

Installation method

Source — CUDA 12 + PyTorch (uv pip install .[cu12-torch])

Kernel backend

cuda_core (default, runtime compilation)

Python version

3.10.20

PyTorch version (if installed)

2.5.1+cu121 / CUDA 12.1

GPU / driver / CUDA toolkit

A100 80GB PCIe, driver 545.23.08, CUDA 12.3

Operating system

Ubuntu 22.04.4 LTS, kernel 6.5.0-15-generic

Isaac Sim version (if applicable)

No response

Additional context

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions