@@ -325,26 +325,32 @@ def preview_trajectory(trajectory: JointTrajectory, joint_names: list[str]) -> N
325325
326326
327327def wait_for_completion (client : CoordinatorClient , task_name : str , timeout : float = 60.0 ) -> bool :
328- """Wait for trajectory to complete with progress display."""
328+ """Wait for trajectory to complete by polling task state.
329+
330+ TrajectoryState is an IntEnum: IDLE=0, EXECUTING=1, COMPLETED=2, ABORTED=3, FAULT=4.
331+ """
329332 start = time .time ()
330- last_progress = - 1.0
333+ _STATE_NAMES = { 0 : "IDLE" , 1 : "EXECUTING" , 2 : "COMPLETED" , 3 : "ABORTED" , 4 : "FAULT" }
331334
332335 while time .time () - start < timeout :
333336 status = client .get_trajectory_status (task_name )
334- if not status .get ("active" , False ):
335- state : str = status .get ("state" , "UNKNOWN" )
336- print (f"\n Trajectory finished: { state } " )
337- return state == "COMPLETED"
337+ if not status :
338+ print ("\n Could not get trajectory status" )
339+ return False
338340
339- progress = status .get ("progress" , 0.0 )
340- if progress != last_progress :
341- bar_len = 30
342- filled = int (bar_len * progress )
343- bar = "=" * filled + "-" * (bar_len - filled )
344- print (f"\r [{ bar } ] { progress * 100 :.1f} %" , end = "" , flush = True )
345- last_progress = progress
341+ state_val = status .get ("state" )
342+ state_name = _STATE_NAMES .get (state_val , f"UNKNOWN({ state_val } )" ) # type: ignore[arg-type]
346343
347- time .sleep (0.05 )
344+ if state_val in (0 , 2 ): # IDLE or COMPLETED
345+ print (f"\n Trajectory finished: { state_name } " )
346+ return True
347+ if state_val in (3 , 4 ): # ABORTED or FAULT
348+ print (f"\n Trajectory failed: { state_name } " )
349+ return False
350+ # state_val == 1 means EXECUTING, keep polling
351+ elapsed = time .time () - start
352+ print (f"\r Executing... ({ elapsed :.1f} s)" , end = "" , flush = True )
353+ time .sleep (0.1 )
348354
349355 print ("\n Timeout waiting for trajectory" )
350356 return False
@@ -476,12 +482,12 @@ def run(self) -> None:
476482
477483 def status (self ) -> None :
478484 """Show task status."""
485+ _STATE_NAMES = {0 : "IDLE" , 1 : "EXECUTING" , 2 : "COMPLETED" , 3 : "ABORTED" , 4 : "FAULT" }
479486 status = self ._client .get_trajectory_status (self ._current_task )
487+ state_val = status .get ("state" )
488+ state_name = _STATE_NAMES .get (state_val , f"UNKNOWN({ state_val } )" ) # type: ignore[arg-type]
480489 print (f"\n Task: { self ._current_task } " )
481- print (f" Active: { status .get ('active' , False )} " )
482- print (f" State: { status .get ('state' , 'UNKNOWN' )} " )
483- if "progress" in status :
484- print (f" Progress: { status ['progress' ] * 100 :.1f} %" )
490+ print (f" State: { state_name } ({ state_val } )" )
485491
486492 def cancel (self ) -> None :
487493 """Cancel active trajectory."""
0 commit comments