What if you could watch your robot's progress live instead of guessing?
Why Action client with feedback in ROS? - Purpose & Use Cases
Imagine you send a robot a command to move to a location, but you have no idea if it's making progress or stuck somewhere.
Without feedback, you can't tell if the robot is working or frozen. You might wait forever or send conflicting commands, causing confusion and errors.
Using an action client with feedback lets you receive updates from the robot as it works, so you know exactly what's happening in real time.
send_goal(goal)
# no updates, just waitsend_goal(goal, feedback_cb=show_progress)
# get live progress updatesThis lets you build smart systems that react to progress, handle delays gracefully, and improve user trust with live status.
Think of a delivery robot that tells you it's halfway to your door, so you can be ready to receive the package.
Manual commands give no progress info, causing uncertainty.
Action clients with feedback provide live updates during tasks.
This improves control, reliability, and user experience.
Practice
Solution
Step 1: Understand the role of an action client
An action client sends goals to an action server and can receive feedback during execution.Step 2: Identify feedback purpose
Feedback callbacks provide real-time progress updates while the task runs.Final Answer:
To send goals to an action server and receive progress updates -> Option BQuick Check:
Action client = send goals + get feedback [OK]
- Thinking action clients only get final results
- Confusing action clients with service clients
- Ignoring feedback callbacks
Solution
Step 1: Recall ROS Python action client syntax
The standard way is to use SimpleActionClient with server name and action type.Step 2: Feedback callback is set separately
Feedback callbacks are registered when sending goals, not in constructor.Final Answer:
client = actionlib.SimpleActionClient('move', MoveAction) -> Option CQuick Check:
SimpleActionClient + feedback_cb separate [OK]
- Passing feedback_cb in constructor (wrong)
- Using ActionClient instead of SimpleActionClient
- Missing action type argument
def feedback_cb(feedback):
print(f"Progress: {feedback.progress}%")
client = actionlib.SimpleActionClient('task', TaskAction)
client.wait_for_server()
goal = TaskGoal()
client.send_goal(goal, feedback_cb=feedback_cb)Solution
Step 1: Understand feedback callback behavior
The feedback_cb prints the progress attribute from feedback with formatting.Step 2: Substitute progress value
If feedback.progress is 50, the print outputs "Progress: 50%" exactly.Final Answer:
Progress: 50% -> Option AQuick Check:
Formatted string with feedback.progress = output [OK]
- Printing variable name instead of value
- Assuming feedback_cb is not called
- Ignoring string formatting
client = actionlib.SimpleActionClient('task', TaskAction)
client.send_goal(TaskGoal(), feedback_cb=feedback_cb)
client.wait_for_server()Solution
Step 1: Check action client usage order
wait_for_server() must be called before sending a goal to ensure server is ready.Step 2: Identify error in code order
Here, send_goal() is called before wait_for_server(), which is incorrect.Final Answer:
wait_for_server() should be called before send_goal() -> Option AQuick Check:
wait_for_server() before send_goal() [OK]
- Calling send_goal before wait_for_server
- Misunderstanding feedback_cb usage
- Assuming feedback_cb is constructor argument
Solution
Step 1: Understand feedback handling for multiple goals
Each goal's feedback should be handled separately to avoid mixing progress updates.Step 2: Use closures or separate callbacks
Creating a unique feedback callback per goal that captures its ID ensures correct feedback association.Final Answer:
Create a new feedback callback function for each goal that captures its goal ID -> Option DQuick Check:
Separate feedback callbacks per goal prevent mix-up [OK]
- Using one callback for all goals causing mixed feedback
- Sending all goals simultaneously without control
- Ignoring feedback defeats purpose of action client
Ready to prove it?
Pass the test and this pattern moves unknown
