Bird
Raised Fist0
ROSframework~5 mins

Preempting actions in ROS

Choose your learning style10 modes available
Introduction

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.

When a robot is moving to a location but needs to go somewhere else immediately.
If a robot is performing a task but a higher priority task comes in.
When a robot's current action is no longer needed or safe to continue.
To cancel a long-running action and replace it with a new one.
When user input changes the robot's goal before the current action finishes.
Syntax
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.

Examples
This cancels the current goal the action client sent.
ROS
client.cancel_goal()
Sends a new goal, which preempts the old one if it is still running.
ROS
client.send_goal(new_goal)
Cancels all goals sent by this client, useful if multiple goals were sent.
ROS
client.cancel_all_goals()
Sample Program

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.

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.")
OutputSuccess
Important Notes

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.

Summary

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

(1/5)
1.

What does cancel_goal() do in ROS action clients?

easy
A. It requests to stop the currently running action goal.
B. It starts a new action goal immediately.
C. It pauses the action without stopping it.
D. It resets the action server to its initial state.

Solution

  1. Step 1: Understand the purpose of cancel_goal()

    This function is used to request the cancellation of the current goal being processed by the action server.
  2. Step 2: Differentiate from other actions

    Starting a new goal or pausing are different operations; cancel_goal() specifically requests stopping the current goal.
  3. Final Answer:

    It requests to stop the currently running action goal. -> Option A
  4. Quick Check:

    cancel_goal() stops current goal [OK]
Hint: Remember: cancel_goal() means stop current action [OK]
Common Mistakes:
  • Confusing cancel_goal() with starting a new goal
  • Thinking cancel_goal() pauses instead of cancels
  • Assuming cancel_goal() resets the server
2.

Which of the following is the correct sequence to preempt an action in ROS?

1. cancel_goal()
2. send_goal(new_goal)
easy
A. Call cancel_goal() first, then send_goal(new_goal).
B. Call send_goal(new_goal) first, then cancel_goal().
C. Call cancel_goal() twice, then send_goal(new_goal).
D. Only call send_goal(new_goal) without canceling.

Solution

  1. Step 1: Understand preempting order

    You must first cancel the current goal to stop it before sending a new goal to replace it.
  2. Step 2: Confirm correct method calls

    Calling cancel_goal() first ensures the old task stops, then send_goal(new_goal) starts the new task.
  3. Final Answer:

    Call cancel_goal() first, then send_goal(new_goal). -> Option A
  4. Quick Check:

    Cancel before sending new goal [OK]
Hint: Cancel first, then send new goal to preempt [OK]
Common Mistakes:
  • Sending new goal before canceling old one
  • Calling cancel_goal() multiple times unnecessarily
  • Skipping cancel_goal() and sending new goal directly
3.

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?

medium
A. Neither goal runs because cancel_goal() stops all actions.
B. goal1 runs fully; goal2 is ignored.
C. Both goal1 and goal2 run simultaneously.
D. goal1 is canceled; goal2 starts running.

Solution

  1. Step 1: Analyze the cancel_goal() effect

    After sending goal1, cancel_goal() requests to stop it immediately.
  2. Step 2: Understand sending goal2

    Sending goal2 after canceling goal1 starts the new action goal.
  3. Final Answer:

    goal1 is canceled; goal2 starts running. -> Option D
  4. Quick Check:

    Cancel old goal, start new goal [OK]
Hint: Cancel stops old goal; new send_goal starts new task [OK]
Common Mistakes:
  • Assuming goal1 runs fully despite cancel
  • Thinking both goals run at once
  • Believing cancel_goal() stops all future goals
4.

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?

medium
A. The code should call cancel_goal() twice to cancel both goals.
B. You cannot send two goals without canceling the first one first.
C. Calling cancel_goal() after sending two goals does not preempt correctly.
D. There is no error; this sequence is correct.

Solution

  1. Step 1: Understand goal handling

    Sending two goals in a row without canceling means the second goal overrides the first immediately.
  2. Step 2: Analyze cancel_goal() timing

    Calling cancel_goal() after both sends only cancels the currently active goal, not preempting properly between goals.
  3. Final Answer:

    Calling cancel_goal() after sending two goals does not preempt correctly. -> Option C
  4. Quick Check:

    Cancel before sending new goal to preempt [OK]
Hint: Cancel before sending next goal, not after [OK]
Common Mistakes:
  • Sending multiple goals without canceling first
  • Assuming cancel_goal() cancels all previous goals
  • Calling cancel_goal() too late to preempt
5.

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)
hard
A. You must call cancel_goal() before checking the state.
B. This approach correctly preempts only after 5 seconds of activity.
C. You should send the new goal first, then cancel the old one.
D. ROS actions do not support checking active time for preemption.

Solution

  1. Step 1: Check action state and duration

    The code checks if the action is active and has been running longer than 5 seconds.
  2. 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.
  3. Final Answer:

    This approach correctly preempts only after 5 seconds of activity. -> Option B
  4. Quick Check:

    Check state and time before canceling [OK]
Hint: Check active state and time before canceling [OK]
Common Mistakes:
  • Canceling without checking active time
  • Sending new goal before canceling old one
  • Assuming ROS lacks timing info for actions
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard