1212from 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
6971class 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
131135def 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