Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
479 changes: 479 additions & 0 deletions .claude/skills/benchmark/SKILL.md

Large diffs are not rendered by default.

32 changes: 26 additions & 6 deletions embodichain/lab/sim/solvers/base_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,12 +313,32 @@ def set_qpos_limits(
)
return False

self.lower_qpos_limits = torch.tensor(
lower_qpos_limits, dtype=float, device=self.device
)
self.upper_qpos_limits = torch.tensor(
upper_qpos_limits, dtype=float, device=self.device
)
if isinstance(lower_qpos_limits, list) or isinstance(
lower_qpos_limits, np.ndarray
):
self.lower_qpos_limits = torch.tensor(
lower_qpos_limits, dtype=float, device=self.device
)
elif isinstance(lower_qpos_limits, torch.Tensor):
self.lower_qpos_limits = lower_qpos_limits.clone().to(device=self.device)
else:
logger.log_error(
f"Invalid type for lower_qpos_limits: {type(lower_qpos_limits)}. Must be list, np.ndarray, or torch.Tensor."
)

if isinstance(upper_qpos_limits, list) or isinstance(
upper_qpos_limits, np.ndarray
):
self.upper_qpos_limits = torch.tensor(
upper_qpos_limits, dtype=float, device=self.device
)
elif isinstance(upper_qpos_limits, torch.Tensor):
self.upper_qpos_limits = upper_qpos_limits.clone().to(device=self.device)
else:
logger.log_error(
f"Invalid type for upper_qpos_limits: {type(upper_qpos_limits)}. Must be list, np.ndarray, or torch.Tensor."
)

return True
Comment on lines +316 to 342
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

set_qpos_limits() logs an error for invalid lower_qpos_limits / upper_qpos_limits types but still returns True, and it may leave one/both of the *_qpos_limits attributes unchanged/None. This can lead to downstream IK sampling using stale or missing limits. Consider returning False (or raising) as soon as an invalid type is detected, and only returning True once both tensors have been successfully set (optionally validating shape matches DOF).

Copilot uses AI. Check for mistakes.

def get_qpos_limits(self) -> dict:
Expand Down
36 changes: 27 additions & 9 deletions scripts/benchmark/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

python -m scripts.benchmark rl --tasks push_cube --algorithms ppo --suite default
python -m scripts.benchmark rl --rebuild-report-only
python -m scripts.benchmark robotics-kinematic-solver
python -m scripts.benchmark robotics-kinematic-solver -s pytorch
"""

from __future__ import annotations
Expand All @@ -29,6 +29,22 @@
import sys


def _run_robotics_kinematic_solver_cli(args: argparse.Namespace) -> None:
"""Run robotics kinematic solver benchmark with forwarded CLI args."""
from scripts.benchmark.robotics.kinematic_solver.run_benchmark import (
run_all_benchmarks,
)

run_all_benchmarks(selected_solvers=args.solvers)


def _run_rl_cli(_: argparse.Namespace) -> None:
"""Run RL benchmark CLI entrypoint."""
from scripts.benchmark.rl.run_benchmark import main as rl_main

rl_main()


def main() -> None:
"""Dispatch to the appropriate benchmark sub-command CLI."""
parser = argparse.ArgumentParser(
Expand All @@ -42,20 +58,22 @@ def main() -> None:
"rl",
help="Run RL benchmark: train, evaluate, aggregate, and report results.",
)
from scripts.benchmark.rl.run_benchmark import main as rl_main

rl_parser.set_defaults(func=rl_main)
rl_parser.set_defaults(func=_run_rl_cli)

# -- robotics-kinematic-solver -------------------------------------------
robotics_ks_parser = subparsers.add_parser(
"robotics-kinematic-solver",
help="Benchmark the OPW kinematic solver (FK/IK accuracy and speed).",
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

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

The subcommand help text still says it benchmarks only the OPW solver, but the CLI now supports both OPW and PyTorch solvers via --solvers. Update the help string to reflect the expanded scope so users aren’t misled.

Suggested change
help="Benchmark the OPW kinematic solver (FK/IK accuracy and speed).",
help="Benchmark kinematic solvers (OPW/PyTorch) for FK/IK accuracy and speed.",

Copilot uses AI. Check for mistakes.
)
from scripts.benchmark.robotics.kinematic_solver.opw_solver import (
benchmark_opw_solver,
robotics_ks_parser.add_argument(
"--solvers",
"-s",
nargs="+",
choices=("opw", "pytorch", "all"),
default=["all"],
help="Solvers to benchmark. Use one or more of: opw, pytorch, all.",
)

robotics_ks_parser.set_defaults(func=benchmark_opw_solver)
robotics_ks_parser.set_defaults(func=_run_robotics_kinematic_solver_cli)

# -- Parse ---------------------------------------------------------------
# If no sub-command is given, print help and exit.
Expand All @@ -73,7 +91,7 @@ def main() -> None:
original_argv = sys.argv
sys.argv = subcommand_argv
try:
known.func()
known.func(known)
finally:
sys.argv = original_argv
else:
Expand Down
Loading
Loading