Skip to content

Commit 0bc10e4

Browse files
committed
Raise exception on partial trajectories
1 parent 60ef710 commit 0bc10e4

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
130130
* Changed `RosDistro` to be an enum instead of string.
131131
* Changed `TargetMode` to be an enum instead of string.
132132
* Changed default values for number of planning attempts in MoveIt to 5, and the allowed planning time to 1 second.
133+
* Changed cartesian motion planner of MoveIt to raise an exception (including the partial trajectory) if fraction is below 1.0 (ie. the trajectory is not possible).
133134

134135
### Removed
135136

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from compas.geometry import Box
2+
from compas.geometry import Frame
3+
4+
from compas_fab.backends import MotionPlanningError
5+
from compas_fab.backends import MoveItPlanner
6+
from compas_fab.backends import RosClient
7+
from compas_fab.robots import FrameWaypoints
8+
from compas_fab.robots import RigidBody
9+
from compas_fab.robots import TargetMode
10+
11+
with RosClient() as client:
12+
robot_cell = client.load_robot_cell()
13+
planner = MoveItPlanner(client)
14+
assert robot_cell.robot_model.name == "ur5_robot"
15+
16+
# Add an obstacle
17+
box_mesh = Box(0.1, 0.1, 1.2).to_mesh(triangulated=True)
18+
robot_cell.rigid_body_models["box"] = RigidBody.from_mesh(box_mesh)
19+
planner.set_robot_cell(robot_cell)
20+
21+
# Define Starting State
22+
start_state = robot_cell.default_cell_state()
23+
start_state.robot_configuration.joint_values = [-3.53, 3.83, -0.58, -3.33, 4.76, 0.00]
24+
# Set the obstacle's position
25+
start_state.rigid_body_states["box"].frame.point = [0.3, 0.0, 0.0]
26+
27+
# Create waypoints
28+
frame = Frame([0.4, 0.3, 0.4], [0, 1, 0], [0, 0, 1])
29+
waypoints = FrameWaypoints([frame], TargetMode.ROBOT)
30+
31+
# This planning is expected to fail because it's impossible to follow the trajectory
32+
# in a linear motion, so the planner will fail but return a partial trajectory.
33+
try:
34+
trajectory = planner.plan_cartesian_motion(waypoints, start_state)
35+
print(f"Trajectory fraction: {trajectory.fraction}")
36+
print(f"Trajectory contains {len(trajectory.points)} configurations (JointTrajectoryPoint).")
37+
print(f"Executing this path at full speed would take approx. {trajectory.time_from_start} seconds.")
38+
except MotionPlanningError as e:
39+
print(f"Motion planning failed: {e}")
40+
print(f"Trajectory fraction: {e.partial_trajectory.fraction}")
41+
print(f"Trajectory contains {len(e.partial_trajectory.points)} configurations (JointTrajectoryPoint).")
42+
43+
44+
"""
45+
Output: (may vary)
46+
>>> Motion planning failed: Motion planning failed
47+
>>> Trajectory fraction: 0.14285714285714285
48+
>>> Trajectory contains 12 configurations (JointTrajectoryPoint).
49+
"""

src/compas_fab/backends/ros/backend_features/move_it_plan_cartesian_motion.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from compas.utilities import await_callback
55

6+
from compas_fab.backends.exceptions import MotionPlanningError
67
from compas_fab.backends.interfaces import PlanCartesianMotion
78
from compas_fab.backends.ros.backend_features.helpers import convert_constraints_to_rosmsg
89
from compas_fab.backends.ros.backend_features.helpers import convert_trajectory
@@ -181,6 +182,8 @@ def response_handler(response):
181182
trajectory = convert_trajectory(
182183
joints, response.solution, response.start_state, response.fraction, None, response
183184
)
185+
if response.fraction < 1:
186+
errback(MotionPlanningError("Motion planning failed", trajectory))
184187
callback(trajectory)
185188
except Exception as e:
186189
errback(e)

0 commit comments

Comments
 (0)