Skip to content

Commit e99fed9

Browse files
committed
Improve exception handling and docstrings
1 parent 5b0b9cb commit e99fed9

File tree

1 file changed

+38
-27
lines changed

1 file changed

+38
-27
lines changed

snp_motion_planning/src/motion_client.py

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
from control_msgs.action import FollowJointTrajectory
1313

1414

15-
def create_dummy_tool_path():
15+
def create_dummy_tool_path() -> ToolPath:
16+
"""Create a dummy ToolPath message for testing purposes."""
1617
pose1 = Pose()
1718

1819
pose1.position.x = 0.1
@@ -37,7 +38,8 @@ def create_dummy_tool_path():
3738
return tool_path
3839

3940

40-
def create_toolpath_from_yaml(file_path):
41+
def create_toolpath_from_yaml(file_path) -> ToolPath:
42+
"""Create a ToolPath message from a YAML file."""
4143
with open(file_path, "r") as file:
4244
data = yaml.safe_load(file)
4345

@@ -67,6 +69,8 @@ def create_toolpath_from_yaml(file_path):
6769

6870

6971
class MotionClient(Node):
72+
"""A ROS2 node for motion planning and robot control."""
73+
7074
def __init__(self):
7175
super().__init__("motion_client")
7276
self.planner = self.create_client(GenerateMotionPlan, "/generate_motion_plan")
@@ -106,50 +110,54 @@ def request_control(self, trajectory: JointTrajectory):
106110
return ctrl_result_future
107111

108112
def request_control_result(self, future):
113+
"""Wait for the result from the action server."""
114+
109115
goal_handle = future.result()
110116
if not goal_handle.accepted:
111117
self.get_logger().info("Goal rejected :(")
112118
return
113119

114120
self.get_logger().info("Goal accepted :)")
115121

116-
self.ctrl_result_future = goal_handle.get_result_async()
117-
self.ctrl_result_future.add_done_callback(self.get_result_callback)
118-
return self.ctrl_result_future
122+
ctrl_result_future = goal_handle.get_result_async()
123+
ctrl_result_future.add_done_callback(self.get_result_callback)
124+
return ctrl_result_future
119125

120126
def get_result_callback(self, future):
121127
result = future.result().result
122-
self.get_logger().info("Result: {0}".format(result.error_code))
128+
self.get_logger().info(f"Result: {result.error_code}")
123129

124130
def feedback_callback(self, feedback_msg):
125131
feedback = feedback_msg.feedback
126-
self.get_logger().info(
127-
"Received feedback: {0}".format(feedback.partial_sequence)
128-
)
132+
self.get_logger().info(f"Received feedback: {feedback.partial_sequence}")
129133

130134

131135
def main(args=None):
132136
rclpy.init(args=args)
133137

134138
client = MotionClient()
135-
try:
136-
plan_future = client.request_plan()
137-
rclpy.spin_until_future_complete(client, plan_future)
138-
139-
response = plan_future.result()
140-
if response.success:
141-
client.get_logger().info("Received motion plan successfully!")
142-
# Example: print number of points in each trajectory
143-
client.get_logger().info(
144-
f"Approach: {len(response.approach.points)} points"
145-
)
146-
client.get_logger().info(f"Process: {len(response.process.points)} points")
147-
# print(response.approach.points)
148-
client.get_logger().info(
149-
f"Departure: {len(response.departure.points)} points"
150-
)
151-
except Exception as e:
152-
client.get_logger().error(f"Service call failed: {e}")
139+
client.get_logger().info("[plan] Requesting motion plan...")
140+
plan_future = client.request_plan()
141+
rclpy.spin_until_future_complete(client, plan_future)
142+
143+
if plan_future.exception():
144+
client.get_logger().error(f"[plan] Request failed: {plan_future.exception()}")
145+
client.destroy_node()
146+
rclpy.shutdown()
147+
return
148+
149+
response = plan_future.result()
150+
151+
if not response or not getattr(response, "success", False):
152+
client.get_logger().error(f"[plan] Request failed: {plan_future.exception()}")
153+
client.destroy_node()
154+
rclpy.shutdown()
155+
return
156+
157+
client.get_logger().info("[plan] Received motion plan successfully!")
158+
client.get_logger().info(f"[plan] Approach: {len(response.approach.points)} points")
159+
client.get_logger().info(f"[plan] Process: {len(response.process.points)} points")
160+
client.get_logger().info(f"[plan] Departure: {len(response.departure.points)} points")
153161

154162
# remove effort values because scaled_joint_trajectory_controller does not support it.
155163
for pt in response.approach.points:
@@ -159,6 +167,8 @@ def main(args=None):
159167
for pt in response.departure.points:
160168
pt.effort = []
161169

170+
client.get_logger().info("\n[exec] Starting Execution...")
171+
162172
# Synchronus control
163173
approach_future = client.request_control(response.approach)
164174
rclpy.spin_until_future_complete(client, approach_future)
@@ -167,6 +177,7 @@ def main(args=None):
167177
departure_future = client.request_control(response.departure)
168178
rclpy.spin_until_future_complete(client, departure_future)
169179

180+
client.get_logger().info("[exec] Execution complete. Exiting.")
170181
client.destroy_node()
171182
rclpy.shutdown()
172183

0 commit comments

Comments
 (0)