robot_agent: Execution States and Waypoint Progression
After fleet_manager and path_planner, the third core module to examine is robot_agent. The manager assigns work, the planner turns it into a route, and the agent turns that route into an observable execution process.
Without the agent, the system could announce assignments without demonstrating that a task ever progressed through execution to completion. This article examines the minimal state machine, its waypoint updates, and the limits of the current model.
The V1 Goal
The agent subscribes to task_assignments, accepts assignments addressed to itself, stores route_waypoints, advances through them periodically, and publishes transitions among idle, executing, and completed.
It converts the planner’s static route into behavior the manager can observe over time. Publishing an assignment and executing one are different events in a distributed system.
Inputs and Outputs
The input is TaskAssignment.msg:
1 | string robot_id |
This is already an execution instruction with a discrete route. The agent does not plan the pickup-to-dropoff path again. It checks whether the assignment belongs to it and tracks how far along the route it has progressed.
The output is RobotState.msg:
1 | string robot_id |
For the manager, the most important fields are status, current_waypoint, and current_task_id: is the robot available, what task is it executing, and which discrete position has it reached?
The agent therefore translates a route sequence into a state sequence.
A State Machine Without an Explicit Enum
robot_agent_node.cpp does not need a formal enum to express clear transitions. Its state is carried by active_task_, completion_announced_, active_task_id_, route_waypoints_, route_index_, and current_waypoint_.
The lifecycle is:
1 | no task |
The intermediate execution phase matters. The agent does not immediately declare completion on receipt, nor does it merely expose a busy Boolean with no visible progress.
Accepting an Assignment
The subscriber applies three checks:
- Ignore a message whose
robot_iddiffers from this agent’s ID. - Reject a new assignment while
active_task_is true. - Ignore an assignment with an empty route.
These rules let several agents share one topic while enforcing the V1 assumption of one active task per robot. The accepted object is an executable assignment, not a partially specified planning request.
On acceptance, the agent marks the task active, resets the completion flag, saves the task ID and route, resets the route index to zero, and sets current_waypoint_ to the first route element.
That last step assumes the planner’s first waypoint represents the robot’s current discrete position. It is consistent with the V1 route contract.
Advancing the Route
A one-second timer invokes publish_state; there is no separate motion-execution thread. The route is not consumed instantly. Each tick publishes a state and, where applicable, advances the route by one waypoint.
No Active Task
The agent publishes idle with an empty task ID.
More Waypoints Remain
When route_index_ + 1 < route_waypoints_.size(), it increments the index, updates the current waypoint, and publishes executing with the active task ID.
The manager sees changing discrete positions, rather than a static busy flag.
The Route Has Ended, but Completion Has Not Been Announced
The next branch publishes completed while retaining the task ID, then sets completion_announced_.
If the task state were cleared immediately, the manager might see only an executing robot followed by an idle robot. The explicit completion tick establishes that the task finished rather than simply disappeared.
Returning to Idle
On the following tick, the agent clears the active flag, task ID, and route; resets the index; and publishes idle.
This two-step ending gives the manager a visible completion state before making the robot available again. It is a useful lifecycle distinction even though this version does not implement an acknowledgment protocol guaranteeing the manager received that one message.
Why the Manager Needs This Feedback
The manager needs to know when execution begins, when the assigned task completes, and when the robot is available for another task. The agent supplies the downstream observations for that lifecycle.
The manager still retains assignment state to avoid relying only on a potentially stale topic sample, but it ultimately needs execution feedback from the robot side.
Without this module, V1 could prove queuing, planning, and assignment publication. With it, the demo also demonstrates route consumption, completion, and robot-resource release.
Mapping Waypoints to Positions
lookup_waypoint_position fills RobotState.pose. It first uses the launch-time waypoint_positions configuration and falls back to the built-in map when a lookup is unavailable.
The demo configuration contains:
1 | dock_a:0.0:0.0 |
demo.launch.py supplies the same map configuration to the planner and both agents. robot_1 starts at dock_a, and robot_2 at dock_c.
The planner owns graph connectivity, while the agent turns waypoint names into position reports. This connects planning and observed state through shared configuration.
The reported pose still jumps discretely between waypoint coordinates. It does not model velocity, changing orientation, or continuous path tracking, so it is demo state rather than a real base-controller observation.
What the Agent Already Provides
Assignments now reach a downstream consumer. Routes advance visibly. Completion is represented explicitly. The execution-state output agrees with the map used at launch. Together, these features close the loop that the manager and planner alone could not demonstrate.
What It Does Not Yet Provide
- Real navigation: motion is simulated by timer-driven waypoint changes; there is no Nav2 or base-controller integration and no real localization feedback.
- Execution failure states: a stuck robot, deviation, lost waypoint, or cancellation has no dedicated lifecycle state yet.
- Preemption or reassignment: an active agent rejects new work rather than interrupting the current task.
- Fine-grained progress: there is no edge-level progress, remaining-time estimate, or richer execution feedback.
- Resource behavior:
battery_percentremains fixed at100.0F; the field exists but does not influence execution.
The agent supports discrete task-execution semantics, not the full semantics of a physical robot.
The Next Questions
The three core responsibilities are now clear: the manager receives and assigns tasks, the planner produces routes, and the agent produces an execution-state stream.
That makes it possible to distinguish the capabilities of the running V1 prototype from reserved interface fields and future work. Conflict handling, stronger scheduling, and real navigation are subsequent increases in complexity. The current agent’s contribution is the reliable demo progression from assignment through visible execution to completion.
If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. All the images used in the blog are my original works or AI works, if you want to take it,don't hesitate. Thank you !