Skip to content

Commit 7681182

Browse files
Improving planners and experiments
1 parent 6c092b2 commit 7681182

File tree

11 files changed

+96
-143
lines changed

11 files changed

+96
-143
lines changed

mm_plan/src/mm_plan/Planners.py

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import numpy as np
77

8+
from mm_utils import parsing
89
from mm_utils.enums import RefType
910
from mm_utils.math import interpolate, wrap_pi_array, wrap_pi_scalar
1011

@@ -142,7 +143,7 @@ def __init__(self, config):
142143

143144
# Parse base pose (optional)
144145
if "base_pose" in config:
145-
self.base_target = np.array(config["base_pose"])
146+
self.base_target = parsing.parse_array(config["base_pose"])
146147
if len(self.base_target) != 3:
147148
raise ValueError(
148149
f"base_pose must be SE2 [x, y, yaw], got {len(self.base_target)} dimensions"
@@ -154,7 +155,7 @@ def __init__(self, config):
154155

155156
# Parse EE pose (optional)
156157
if "ee_pose" in config:
157-
self.ee_target = np.array(config["ee_pose"])
158+
self.ee_target = parsing.parse_array(config["ee_pose"])
158159
if len(self.ee_target) != 6:
159160
raise ValueError(
160161
f"ee_pose must be SE3 [x, y, z, roll, pitch, yaw], got {len(self.ee_target)} dimensions"
@@ -170,10 +171,23 @@ def __init__(self, config):
170171
)
171172

172173
# Common parameters
173-
self.tracking_err_tol = config.get("tracking_err_tol", 0.02)
174+
self.tracking_pos_err_tol = config.get("tracking_pos_err_tol", 0.02)
174175
self.tracking_ori_err_tol = config.get("tracking_ori_err_tol", 0.1)
175176
self.hold_period = config.get("hold_period", 0.0)
176177

178+
# Parse masks to specify which dimensions matter for completion
179+
# base_mask: [x, y, yaw] - True means that dimension is checked
180+
if "base_mask" in config:
181+
self.base_mask = np.array(config["base_mask"], dtype=bool)
182+
else:
183+
self.base_mask = np.ones(3, dtype=bool)
184+
185+
# ee_mask: [x, y, z, roll, pitch, yaw] - True means that dimension is checked
186+
if "ee_mask" in config:
187+
self.ee_mask = np.array(config["ee_mask"], dtype=bool)
188+
else:
189+
self.ee_mask = np.ones(6, dtype=bool)
190+
177191
# State tracking
178192
self.finished = False
179193
self.base_reached = False
@@ -224,10 +238,19 @@ def checkFinished(self, t, states):
224238
# Check base if applicable
225239
if self.has_base_ref:
226240
base_pose = states["base"]["pose"]
227-
pos_err = np.linalg.norm(base_pose[:2] - self.base_target[:2])
228-
yaw_err = abs(wrap_pi_scalar(base_pose[2] - self.base_target[2]))
229-
pos_within_tol = pos_err < self.tracking_err_tol
230-
ori_within_tol = yaw_err < self.tracking_ori_err_tol
241+
242+
# Check position (x, y) only if mask indicates it matters
243+
pos_mask = self.base_mask[:2]
244+
pos_err = np.linalg.norm((base_pose[:2] - self.base_target[:2])[pos_mask])
245+
pos_within_tol = pos_err < self.tracking_pos_err_tol
246+
247+
# Check orientation (yaw) only if mask indicates it matters
248+
if self.base_mask[2]:
249+
yaw_err = abs(wrap_pi_scalar(base_pose[2] - self.base_target[2]))
250+
ori_within_tol = yaw_err < self.tracking_ori_err_tol
251+
else:
252+
ori_within_tol = True
253+
yaw_err = 0.0
231254

232255
if pos_within_tol and ori_within_tol:
233256
if not self.base_reached:
@@ -246,10 +269,16 @@ def checkFinished(self, t, states):
246269
# Check EE if applicable
247270
if self.has_ee_ref:
248271
ee_pose = states["EE"]["pose"]
249-
pos_err = np.linalg.norm(ee_pose[:3] - self.ee_target[:3])
272+
273+
# Check position (x, y, z) only if mask indicates it matters
274+
pos_mask = self.ee_mask[:3]
275+
pos_err = np.linalg.norm((ee_pose[:3] - self.ee_target[:3])[pos_mask])
276+
pos_within_tol = pos_err < self.tracking_pos_err_tol
277+
278+
# Check orientation (roll, pitch, yaw) only if mask indicates it matters
279+
ori_mask = self.ee_mask[3:]
250280
ori_diff = wrap_pi_array(ee_pose[3:] - self.ee_target[3:])
251-
ori_err = np.linalg.norm(ori_diff)
252-
pos_within_tol = pos_err < self.tracking_err_tol
281+
ori_err = np.linalg.norm(ori_diff[ori_mask])
253282
ori_within_tol = ori_err < self.tracking_ori_err_tol
254283

255284
if pos_within_tol and ori_within_tol:
@@ -305,7 +334,10 @@ def __init__(self, config):
305334

306335
# Parse base path (optional)
307336
if "base_path" in config:
308-
base_path = np.array(config["base_path"])
337+
# Parse each row to handle pi notation
338+
base_path = np.array(
339+
[parsing.parse_array(row) for row in config["base_path"]]
340+
)
309341
if base_path.shape[1] != 3:
310342
raise ValueError(
311343
f"base_path must be SE2 [x, y, yaw], got shape {base_path.shape}"
@@ -318,7 +350,8 @@ def __init__(self, config):
318350

319351
# Parse EE path (optional)
320352
if "ee_path" in config:
321-
ee_path = np.array(config["ee_path"])
353+
# Parse each row to handle pi notation
354+
ee_path = np.array([parsing.parse_array(row) for row in config["ee_path"]])
322355
if ee_path.shape[1] != 6:
323356
raise ValueError(
324357
f"ee_path must be SE3 [x, y, z, roll, pitch, yaw], got shape {ee_path.shape}"
@@ -335,7 +368,7 @@ def __init__(self, config):
335368
)
336369

337370
# Common parameters
338-
self.tracking_err_tol = config.get("tracking_err_tol", 0.02)
371+
self.tracking_pos_err_tol = config.get("tracking_pos_err_tol", 0.02)
339372
self.tracking_ori_err_tol = config.get("tracking_ori_err_tol", 0.1)
340373
self.end_stop = config.get("end_stop", False)
341374

@@ -472,7 +505,7 @@ def checkFinished(self, t, states):
472505
base_vel = states["base"].get("velocity")
473506
end_pose = self.base_plan["p"][-1]
474507
pos_err, ori_err = self._compute_error(base_pose, end_pose, is_base=True)
475-
pos_cond = pos_err < self.tracking_err_tol
508+
pos_cond = pos_err < self.tracking_pos_err_tol
476509
ori_cond = ori_err < self.tracking_ori_err_tol
477510
pos_ori_cond = pos_cond and ori_cond
478511
vel_cond = base_vel is not None and np.linalg.norm(base_vel) < 1e-2
@@ -490,7 +523,7 @@ def checkFinished(self, t, states):
490523
ee_vel = states["EE"].get("velocity")
491524
end_pose = self.ee_plan["p"][-1]
492525
pos_err, ori_err = self._compute_error(ee_pose, end_pose, is_base=False)
493-
pos_cond = pos_err < self.tracking_err_tol
526+
pos_cond = pos_err < self.tracking_pos_err_tol
494527
ori_cond = ori_err < self.tracking_ori_err_tol
495528
pos_ori_cond = pos_cond and ori_cond
496529
vel_cond = ee_vel is not None and np.linalg.norm(ee_vel) < 1e-2

mm_plan/src/mm_plan/TaskManager.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,13 @@ def update(self, t, states):
156156
"All tasks completed (%d/%d)", self.planner_num, self.planner_num
157157
)
158158
return True, 1
159-
160-
return False, 1
159+
else:
160+
self.logger.info(
161+
"Working on task %d/%d",
162+
self.curr_task_id + 1,
163+
self.planner_num,
164+
)
165+
return False, 1
161166

162167
def print(self):
163168
"""Print task manager status."""

mm_run/config/3d_collision.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ planner:
55
planner_type: "WaypointPlanner"
66
ee_pose: [0.0, 1.0, 0.0, 0.0, 0.0, 0.0] # [x, y, z, roll, pitch, yaw]
77
hold_period: 3.0
8-
tracking_err_tol: 0.02
8+
tracking_pos_err_tol: 0.02
99

1010
simulation:
1111
robot:

mm_run/config/configuration.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ planner:
3636
tasks:
3737
- name: str # Task identifier
3838
planner_type: "WaypointPlanner" | "PathPlanner"
39-
tracking_err_tol: float # Position error tolerance [m]
39+
tracking_pos_err_tol: float # Position error tolerance [m]
4040
tracking_ori_err_tol: float # Optional: orientation error tolerance [rad] (default: 0.1)
4141
```
4242
@@ -47,20 +47,20 @@ planner:
4747
planner_type: "WaypointPlanner"
4848
base_pose: [x, y, yaw] # Optional: SE2 [m, m, rad] in world frame
4949
ee_pose: [x, y, z, roll, pitch, yaw] # Optional: SE3 [m, m, m, rad, rad, rad] in world frame
50-
tracking_err_tol: 0.1
50+
tracking_pos_err_tol: 0.1
5151
hold_period: 1.0 # Optional: hold time at target [s]
5252

5353
# Sequential: Only base moves
5454
- name: "Move Base"
5555
planner_type: "WaypointPlanner"
5656
base_pose: [2.0, 1.0, 0.0]
57-
tracking_err_tol: 0.2
57+
tracking_pos_err_tol: 0.2
5858

5959
# Sequential: Only EE moves
6060
- name: "Reach Down"
6161
planner_type: "WaypointPlanner"
6262
ee_pose: [2.2, 1.2, 0.5, 1.57, 0, 0]
63-
tracking_err_tol: 0.05
63+
tracking_pos_err_tol: 0.05
6464
hold_period: 1.0
6565
```
6666
@@ -72,22 +72,22 @@ planner:
7272
base_path: [[x1, y1, yaw1], [x2, y2, yaw2], ...] # Optional: Array of SE2 poses
7373
ee_path: [[x1, y1, z1, r1, p1, y1], [x2, y2, z2, r2, p2, y2], ...] # Optional: Array of SE3 poses
7474
dt: 0.1 # Time step between path points [s]
75-
tracking_err_tol: 0.1
75+
tracking_pos_err_tol: 0.1
7676
end_stop: false # Optional: require zero velocity at end (default: false)
7777

7878
# Sequential: Only base path
7979
- name: "Base Path"
8080
planner_type: "PathPlanner"
8181
base_path: [[0, 0, 0], [1, 0, 0], [2, 1, 1.57]]
8282
dt: 0.1
83-
tracking_err_tol: 0.2
83+
tracking_pos_err_tol: 0.2
8484

8585
# Sequential: Only EE path
8686
- name: "EE Path"
8787
planner_type: "PathPlanner"
8888
ee_path: [[1, 0, 1, 0, 0, 0], [1.5, 0.2, 0.8, 0, 0, 0]]
8989
dt: 0.1
90-
tracking_err_tol: 0.02
90+
tracking_pos_err_tol: 0.02
9191
```
9292
9393
**Note**: At least one of `base_pose`/`base_path` or `ee_pose`/`ee_path` must be specified. Tasks execute sequentially, but each task can coordinate base and EE simultaneously.

mm_run/config/simple_experiment.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ planner:
1111
- name: Base Waypoint
1212
planner_type: WaypointPlanner
1313
base_pose: [3.5, 0.4, 3.14] # x, y, yaw in world frame
14-
tracking_err_tol: 0.2
14+
tracking_pos_err_tol: 0.2
1515

1616
# Task 2: Move end-effector to target pose (SE3: x, y, z, roll, pitch, yaw)
1717
- name: EE Waypoint
1818
planner_type: WaypointPlanner
1919
ee_pose: [1.5, 0.4, 1.0, 3.14, 0, 0] # x, y, z, roll, pitch, yaw - EE pointing down
2020
hold_period: 1.0
21-
tracking_err_tol: 0.05
21+
tracking_pos_err_tol: 0.05
2222

2323
controller:
2424
# Enable self-collision avoidance (prevents robot from colliding with itself)

mm_run/config/test_experiments/experiments.md

Lines changed: 0 additions & 54 deletions
This file was deleted.

mm_run/config/test_experiments/test_complex_sequence.yaml renamed to mm_run/config/test_experiments/test_complex_waypoints.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Integration Test: Complex Multi-Task Sequence
2-
# Tests: Sequential base + EE tasks with consistent state dictionary format
2+
# Tests: Sequential base + EE waypoints
33
# This verifies that TaskManager correctly sequences multiple tasks
44
# and that state conversion (pose + velocity) works throughout
55

@@ -9,13 +9,13 @@ planner:
99
planner_type: WaypointPlanner
1010
base_pose: [0.5, 0.0, 0] # World frame: [x, y, yaw]
1111
ee_pose: [1.2, 0.2, 0.9, 0, 0, 0] # World frame: [x, y, z, roll, pitch, yaw]
12-
tracking_err_tol: 0.5
12+
tracking_pos_err_tol: 0.5
1313
tracking_ori_err_tol: 0.5
1414
- name: Move 2
1515
planner_type: WaypointPlanner
1616
base_pose: [2.0, 0.5, 1.57] # World frame: [x, y, yaw]
1717
ee_pose: [2.2, 0.7, 1.0, 1.57, 0, 0] # World frame: [x, y, z, roll, pitch, yaw]
18-
tracking_err_tol: 0.2
18+
tracking_pos_err_tol: 0.2
1919

2020
controller:
2121
self_collision_avoidance_enabled: True

mm_run/config/test_experiments/test_end_stop_velocity.yaml

Lines changed: 0 additions & 39 deletions
This file was deleted.

mm_run/config/test_experiments/test_orientation_tracking.yaml renamed to mm_run/config/test_experiments/test_orientation_only.yaml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,29 @@
55

66
planner:
77
tasks:
8-
- name: EE Orientation Change
8+
- name: EE Orientation Facing Down
99
planner_type: WaypointPlanner
10-
ee_pose: [1.0, 0.0, 0.8, 0, 0, 0] # World frame: [x, y, z, roll, pitch, yaw]
11-
tracking_err_tol: 0.05
12-
- name: EE Rotate 180
10+
ee_pose: [3, 0, 0, -1pi, 0, 0] # World frame: [x, y, z, roll, pitch, yaw]
11+
ee_mask: [false, false, false, true, true, true] # Only orientation matters
12+
tracking_ori_err_tol: 0.05
13+
- name: EE Orientation Facing Backwards
1314
planner_type: WaypointPlanner
14-
ee_pose: [1.0, 0.0, 0.8, 3.14, 0, 0] # Same position, rotate 180° around x-axis (world frame)
15-
tracking_err_tol: 0.05
15+
ee_pose: [0, 2, 0, -1pi, 0.5pi, 0] # World frame: [x, y, z, roll, pitch, yaw]
16+
ee_mask: [false, false, false, true, true, true] # Only orientation matters
17+
tracking_ori_err_tol: 0.05
1618

1719
controller:
1820
self_collision_avoidance_enabled: True
1921
static_obstacles_collision_avoidance_enabled: False
2022
acados:
2123
name: "TestOrientationTracking"
24+
cost_params:
25+
EEPose:
26+
Qk: [0, 0, 0, 3, 3, 3] # [x, y, z, roll, pitch, yaw]
27+
P: [0, 0, 0, 1, 1, 1] # Terminal weights
2228

2329
simulation:
24-
duration: 8
30+
duration: 6
2531

2632
include:
2733
- package: "mm_run"

0 commit comments

Comments
 (0)