Preempting actions lets a robot stop what it is doing and start a new task quickly. This helps the robot stay flexible and respond to changes fast.
Preempting actions in ROS
action_client.cancel_goal() # or action_client.send_goal(new_goal, done_cb=None, active_cb=None, feedback_cb=None)
cancel_goal() tells the server to stop the current action.
Sending a new goal after canceling preempts the old one.
client.cancel_goal()
client.send_goal(new_goal)
client.cancel_all_goals()
This example sends a robot to point (1,1). After 2 seconds, it cancels that goal and sends a new goal to (2,2). This shows how to preempt an action in ROS.
import rospy import actionlib from move_base_msgs.msg import MoveBaseAction, MoveBaseGoal def move_to_point(client, x, y): goal = MoveBaseGoal() goal.target_pose.header.frame_id = "map" goal.target_pose.header.stamp = rospy.Time.now() goal.target_pose.pose.position.x = x goal.target_pose.pose.position.y = y goal.target_pose.pose.orientation.w = 1.0 client.send_goal(goal) rospy.init_node('preempt_example') client = actionlib.SimpleActionClient('move_base', MoveBaseAction) client.wait_for_server() # Send first goal move_to_point(client, 1.0, 1.0) rospy.sleep(2) # Let robot start moving # Preempt with new goal client.cancel_goal() move_to_point(client, 2.0, 2.0) rospy.loginfo("Sent new goal, preempted old one.")
Preempting helps robots react quickly to new commands.
Always check if the action server supports preemption.
Canceling a goal does not guarantee immediate stop; the server decides when to stop.
Preempting lets you stop a running action and start a new one.
Use cancel_goal() to request stopping the current action.
Send a new goal after canceling to replace the old task.
Practice
What does cancel_goal() do in ROS action clients?
Solution
Step 1: Understand the purpose of
This function is used to request the cancellation of the current goal being processed by the action server.cancel_goal()Step 2: Differentiate from other actions
Starting a new goal or pausing are different operations;cancel_goal()specifically requests stopping the current goal.Final Answer:
It requests to stop the currently running action goal. -> Option AQuick Check:
cancel_goal()stops current goal [OK]
- Confusing cancel_goal() with starting a new goal
- Thinking cancel_goal() pauses instead of cancels
- Assuming cancel_goal() resets the server
Which of the following is the correct sequence to preempt an action in ROS?
1. cancel_goal()
2. send_goal(new_goal)Solution
Step 1: Understand preempting order
You must first cancel the current goal to stop it before sending a new goal to replace it.Step 2: Confirm correct method calls
Callingcancel_goal()first ensures the old task stops, thensend_goal(new_goal)starts the new task.Final Answer:
Call cancel_goal() first, then send_goal(new_goal). -> Option AQuick Check:
Cancel before sending new goal [OK]
- Sending new goal before canceling old one
- Calling cancel_goal() multiple times unnecessarily
- Skipping cancel_goal() and sending new goal directly
Given this ROS action client code snippet, what will be the output behavior?
client.send_goal(goal1)
client.cancel_goal()
client.send_goal(goal2)What happens to goal1 and goal2?
Solution
Step 1: Analyze the cancel_goal() effect
After sendinggoal1,cancel_goal()requests to stop it immediately.Step 2: Understand sending
Sendinggoal2goal2after cancelinggoal1starts the new action goal.Final Answer:
goal1 is canceled; goal2 starts running. -> Option DQuick Check:
Cancel old goal, start new goal [OK]
- Assuming goal1 runs fully despite cancel
- Thinking both goals run at once
- Believing cancel_goal() stops all future goals
Identify the error in this ROS action client code snippet:
client.send_goal(goal1)
client.send_goal(goal2)
client.cancel_goal()What is wrong with this sequence?
Solution
Step 1: Understand goal handling
Sending two goals in a row without canceling means the second goal overrides the first immediately.Step 2: Analyze cancel_goal() timing
Callingcancel_goal()after both sends only cancels the currently active goal, not preempting properly between goals.Final Answer:
Calling cancel_goal() after sending two goals does not preempt correctly. -> Option CQuick Check:
Cancel before sending new goal to preempt [OK]
- Sending multiple goals without canceling first
- Assuming cancel_goal() cancels all previous goals
- Calling cancel_goal() too late to preempt
You want to preempt a running action only if it has been active for more than 5 seconds. Which approach correctly implements this logic?
if client.get_state() == ACTIVE and client.get_time_active() > 5:
client.cancel_goal()
client.send_goal(new_goal)Solution
Step 1: Check action state and duration
The code checks if the action is active and has been running longer than 5 seconds.Step 2: Cancel and send new goal conditionally
Only if both conditions are true, it cancels the current goal and sends a new one, correctly preempting.Final Answer:
This approach correctly preempts only after 5 seconds of activity. -> Option BQuick Check:
Check state and time before canceling [OK]
- Canceling without checking active time
- Sending new goal before canceling old one
- Assuming ROS lacks timing info for actions
Ready to prove it?
Pass the test and this pattern moves unknown
