Skip to content

Commit 7196be7

Browse files
authored
Merge pull request #247 from NVlabs/fix_trajectory_evaluation
2 parents 1e0b5a8 + e6a5ab2 commit 7196be7

File tree

4 files changed

+84
-3
lines changed

4 files changed

+84
-3
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ its affiliates is strictly prohibited.
1010
-->
1111
# Changelog
1212

13+
## Latest Commit
14+
15+
### BugFixes & Misc.
16+
- Fix bug in evaluator to account for dof maximum acceleration and jerk.
17+
- Add unit test for different acceleration and jerk limits.
18+
1319
## Version 0.7.2
1420

1521
### New Features

src/curobo/types/state.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def __post_init__(self):
8181
@staticmethod
8282
def from_numpy(
8383
joint_names: List[str],
84-
position: np.ndarry,
84+
position: np.ndarray,
8585
velocity: Optional[np.ndarray] = None,
8686
acceleration: Optional[np.ndarray] = None,
8787
jerk: Optional[np.ndarray] = None,
@@ -91,6 +91,8 @@ def from_numpy(
9191
vel = acc = je = None
9292
if velocity is not None:
9393
vel = tensor_args.to_device(velocity)
94+
else:
95+
vel = pos * 0.0
9496
if acceleration is not None:
9597
acc = tensor_args.to_device(acceleration)
9698
else:

src/curobo/wrap/reacher/evaluator.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,13 @@ def compute_smoothness(
218218
scale_dt = (1 / dt_score).view(-1, 1, 1)
219219
abs_acc = torch.abs(acc) * (scale_dt**2)
220220
# mean_acc_val = torch.max(torch.mean(abs_acc, dim=-1), dim=-1)[0]
221-
max_acc_val = torch.max(torch.max(abs_acc, dim=-1)[0], dim=-1)[0]
221+
max_acc_val = torch.max(abs_acc, dim=-2)[0] # batch x dof
222222
abs_jerk = torch.abs(jerk) * scale_dt**3
223223
# calculate max mean jerk:
224224
# mean_jerk_val = torch.max(torch.mean(abs_jerk, dim=-1), dim=-1)[0]
225-
max_jerk_val = torch.max(torch.max(abs_jerk, dim=-1)[0], dim=-1)[0]
225+
max_jerk_val = torch.max(abs_jerk, dim=-2)[0] # batch x dof
226226
acc_label = torch.logical_and(max_acc_val <= max_acc, max_jerk_val <= max_jerk)
227+
acc_label = torch.all(acc_label, dim=-1)
227228
return (acc_label, smooth_cost(abs_acc, abs_jerk, dt_score))
228229

229230

tests/motion_gen_eval_test.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#
2+
# Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
#
4+
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
5+
# property and proprietary rights in and to this material, related
6+
# documentation and any modifications thereto. Any use, reproduction,
7+
# disclosure or distribution of this material and related documentation
8+
# without an express license agreement from NVIDIA CORPORATION or
9+
# its affiliates is strictly prohibited.
10+
#
11+
12+
# Third Party
13+
import pytest
14+
import torch
15+
16+
# CuRobo
17+
from curobo.types.base import TensorDeviceType
18+
from curobo.types.robot import JointState
19+
from curobo.util_file import get_robot_configs_path, join_path, load_yaml
20+
from curobo.wrap.reacher.evaluator import TrajEvaluatorConfig
21+
from curobo.wrap.reacher.motion_gen import MotionGen, MotionGenConfig, MotionGenPlanConfig
22+
23+
24+
def run_motion_gen(robot_file, evaluate_interpolated_trajectory, max_acc, max_jerk):
25+
tensor_args = TensorDeviceType()
26+
world_file = "collision_test.yml"
27+
robot_data = load_yaml(join_path(get_robot_configs_path(), robot_file))
28+
dof = len(robot_data["robot_cfg"]["kinematics"]["cspace"]["joint_names"])
29+
30+
robot_data["robot_cfg"]["kinematics"]["cspace"]["max_acceleration"] = [
31+
max_acc for i in range(9)
32+
]
33+
robot_data["robot_cfg"]["kinematics"]["cspace"]["max_jerk"] = [max_jerk for i in range(9)]
34+
35+
motion_gen_config = MotionGenConfig.load_from_robot_config(
36+
robot_data,
37+
world_file,
38+
tensor_args,
39+
use_cuda_graph=False,
40+
maximum_trajectory_dt=1.5,
41+
evaluate_interpolated_trajectory=evaluate_interpolated_trajectory,
42+
)
43+
motion_gen = MotionGen(motion_gen_config)
44+
45+
retract_cfg = motion_gen.get_retract_config()
46+
47+
start_state = JointState.from_position(retract_cfg.view(1, -1).clone())
48+
goal_state = JointState.from_position(retract_cfg.view(1, -1).clone() + 0.2)
49+
50+
result = motion_gen.plan_single_js(
51+
start_state, goal_state, MotionGenPlanConfig(max_attempts=5, enable_graph_attempt=10)
52+
)
53+
return result
54+
55+
56+
@pytest.mark.parametrize(
57+
"robot_file, evaluate_interpolated_traj, max_acc, max_jerk",
58+
[
59+
("franka.yml", False, 1.0, 500.0),
60+
("franka.yml", True, 0.1, 500.0),
61+
("franka.yml", True, 1.0, 500.0),
62+
("ur5e.yml", False, 1.0, 500.0),
63+
("ur5e.yml", True, 0.1, 500.0),
64+
("ur5e.yml", True, 1.0, 500.0),
65+
],
66+
)
67+
def test_motion_gen_trajectory(robot_file, evaluate_interpolated_traj, max_acc, max_jerk):
68+
result = run_motion_gen(robot_file, evaluate_interpolated_traj, max_acc, max_jerk)
69+
70+
assert result.success.item()
71+
assert torch.max(torch.abs(result.optimized_plan.acceleration)) <= max_acc
72+
assert torch.max(torch.abs(result.optimized_plan.jerk)) <= max_jerk

0 commit comments

Comments
 (0)