Skip to content

Commit 162b464

Browse files
committed
reworked sequence/State flow.
1 parent bc3f75c commit 162b464

1 file changed

Lines changed: 42 additions & 58 deletions

File tree

src/percussion_task_manager/percussion_task_manager/task_manager_node.py

Lines changed: 42 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def __init__(self) -> None:
5353
self._selected_marker: Optional[Pose6D] = None
5454
self._current_state = TaskState.IDLE
5555
self._pending_capture_call = None
56-
self._returning = False
56+
self._on_sequence_done = None
5757
self._sequence: List[dict] = []
5858

5959
self.publish_state(self._current_state)
@@ -138,11 +138,11 @@ def _build_return_sequence(self) -> List[dict]:
138138
'marker_pose': _make_pose6d(),
139139
'approach_offset': [0.0, 0.0, 0.0, 0.0, 1.57, 0.0], # TCP frame
140140
},
141-
#{
142-
# 'motion_type': 'RETURN_HOME',
143-
# 'marker_pose': _make_pose6d(),
144-
# 'approach_offset': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
145-
#},
141+
{
142+
'motion_type': 'RETURN_HOME',
143+
'marker_pose': _make_pose6d(),
144+
'approach_offset': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
145+
},
146146
]
147147

148148
# ------------------------------------------------------------------
@@ -160,34 +160,36 @@ def _on_state_changed(self, _msg: String) -> None:
160160

161161
pass
162162
case TaskState.POSE_ACQUIRED:
163-
# marker_pose = self._selected_marker
163+
# ENKEL VOOR THUIS TESTEN... ANDERS NIET GEBRUIKEN!
164+
# self._selected_marker = _make_pose6d(0.6597723446915864, 0.4272507575618981, 0.486163269104955, 1.6956424868194673, 0.7053985046295215, 1.8109614421292222)
164165
if self._selected_marker is None:
165166
self.get_logger().error('POSE_ACQUIRED but no marker available')
166167
self.publish_state(TaskState.ERROR)
167168
return
168169

169170
self._sequence = self._build_sequence(self._selected_marker)
170-
self.get_logger().info(f'sequence: {self._sequence}')
171-
self._returning = False
171+
self._on_sequence_done = lambda: self.publish_state(TaskState.AT_MARKER)
172172
self._execute_next_step()
173-
self.publish_state(TaskState.MOVING_TO_WEDGELOCK)
174173
case TaskState.AT_MARKER:
175-
# Check low level readiness
176-
# Request hammering action
174+
# arduino handshake / readiness check goes here in future
177175
self.publish_state(TaskState.HAMMERING)
178176
pass
179177
case TaskState.HAMMERING:
180178
# wait for result from arduino
181-
self.get_logger().info(f'sequence: {self._sequence}')
179+
182180
self.publish_state(TaskState.DONE)
181+
pass
183182
case TaskState.DONE:
184-
self._sequence = self._build_return_sequence()
185-
self._returning = True
186-
self.get_logger().info(f'sequence: {self._sequence}')
187-
self._execute_next_step()
183+
# Transition logic will go here
188184
self.publish_state(TaskState.RETURNING)
189185
pass
186+
case TaskState.RETURNING:
187+
# Transition logic will go here
188+
self._sequence = self._build_return_sequence()
189+
self._on_sequence_done = lambda: self.publish_state(TaskState.IDLE)
190+
self._execute_next_step()
190191
case _:
192+
191193
pass
192194

193195

@@ -266,48 +268,25 @@ def _on_capture_done(self, future) -> None:
266268
% (selected.marker_id, selected.pose.x, selected.pose.y, selected.pose.z)
267269
)
268270

269-
270271
self._selected_marker = selected.pose
271-
272-
273272
self.publish_state(TaskState.POSE_ACQUIRED)
274273

275-
276-
# Rework to be more general motion.
277-
278-
279-
#self._sequence = self._build_sequence(selected.pose)
280-
#self._returning = False
281-
#self._execute_next_step()
282-
283274
# ------------------------------------------------------------------
284275
# Sequence execution
285276
# ------------------------------------------------------------------
286277

287-
def _execute_next_step(self) -> None:
278+
def _execute_next_step(self) -> bool:
288279
if not self._sequence:
289-
self.get_logger().info(f'if not self.sequence')
290-
if not self._returning:
291-
self.publish_state(TaskState.AT_MARKER)
292-
# Main sequence done — start return sequence
293-
# self._returning = True
294-
# self._sequence = self._build_return_sequence()
295-
# self.publish_state(TaskState.HAMMERING)
296-
# self.get_logger().info(f'Hammer sequence . . . ')
297-
# self.publish_state(TaskState.DONE)
298-
pass
299-
else:
300-
# Return sequence done — back to idle
301-
self.publish_state(TaskState.IDLE)
302-
return
280+
if self._on_sequence_done:
281+
self._on_sequence_done()
282+
return True
303283

304284
step = self._sequence.pop(0)
305-
phase = 'RETURNING' if self._returning else 'MOVING_TO_WEDGELOCK'
306285
self.get_logger().info(
307-
f'{phase} step: {step["motion_type"]} '
308-
f'({len(self._sequence)} steps remaining)'
286+
f'Step: {step["motion_type"]} ({len(self._sequence)} steps remaining)'
309287
)
310288
self._send_motion_goal(step)
289+
return False
311290

312291
def _send_motion_goal(self, step: dict) -> None:
313292
if step['marker_pose'] is None:
@@ -325,27 +304,32 @@ def _send_motion_goal(self, step: dict) -> None:
325304
goal.marker_pose = step['marker_pose']
326305
goal.approach_offset = step['approach_offset']
327306

328-
#state = TaskState.RETURNING if self._returning else TaskState.MOVING_TO_WEDGELOCK
329-
#self.publish_state(state)
330-
send_future = self._motion_client.send_goal_async(goal)
331-
send_future.add_done_callback(self._on_motion_goal_accepted)
307+
def _on_goal_response(future):
308+
handle = future.result()
309+
if not handle.accepted:
310+
self.get_logger().error('Motion goal rejected by motion node.')
311+
self.publish_state(TaskState.ERROR)
312+
return
313+
handle.get_result_async().add_done_callback(self._on_motion_result)
332314

333-
def _on_motion_goal_accepted(self, future) -> None:
334-
goal_handle = future.result()
335-
if not goal_handle.accepted:
336-
self.get_logger().error('Motion goal rejected by motion node.')
337-
self.publish_state(TaskState.ERROR)
338-
return
339-
goal_handle.get_result_async().add_done_callback(self._on_motion_result)
315+
self._motion_client.send_goal_async(goal).add_done_callback(_on_goal_response)
340316

341317
def _on_motion_result(self, future) -> None:
342-
result = future.result().result
318+
try:
319+
result = future.result().result
320+
except Exception as exc:
321+
self.get_logger().error(f'Motion action failed (server may have crashed): {exc}')
322+
self._sequence.clear()
323+
self._on_sequence_done = None
324+
self.publish_state(TaskState.ERROR)
325+
return
343326
if result.success:
344327
self.get_logger().info('Step complete.')
345328
self._execute_next_step()
346329
else:
347330
self.get_logger().error(f'Step failed: {result.message}')
348331
self._sequence.clear()
332+
self._on_sequence_done = None
349333
self.publish_state(TaskState.ERROR)
350334

351335

0 commit comments

Comments
 (0)