Actions
ROS2 actions are designed for long-running tasks that provide feedback during execution and can be cancelled. Unlike services (which are synchronous request-response), actions allow you to monitor progress and interrupt execution. Common examples include navigation goals, arm trajectories, and robot behaviors.
When to Use Actions vs Services
Use Actions when:
- Task takes significant time to complete (seconds to minutes)
- You need progress feedback during execution
- Task should be cancellable mid-execution
- Examples: navigation goals, arm movements, robot behaviors
Use Services when:
- Task completes quickly (milliseconds)
- No progress feedback needed
- Examples: getting parameters, triggering snapshots, simple calculations
listActions()
List all available ROS2 action servers.
Returns: Promise<Array<{name: string, type: string}>> - Array of action servers with names and types
// JavaScript
const actions = await oloClient.core.listActions();
console.log('Available actions:', actions);
// Output: [{ name: '/my_action', type: 'my_pkg/action/MyAction' }, ...]
// Filter by package name
const robotActions = actions.filter(a => a.type && a.type.includes('my_pkg'));
console.log('Robot actions:', robotActions);getActionsForNode(nodeName)
Get actions for a specific ROS2 node with reliable type information. This method uses ros2 node info which always returns action types correctly.
Parameters:
nodeName(string) - The ROS2 node name (e.g., '/bt_navigator')
Returns: Promise<Array<{name: string, type: string}>> - Array of actions with names and types
// JavaScript
const actions = await oloClient.core.getActionsForNode('/bt_navigator');
console.log('Actions for bt_navigator:', actions);
// Output: [{ name: '/navigate_to_pose', type: 'nav2_msgs/action/NavigateToPose' }, ...]getActionGoalStructure(actionType)
Get the goal message structure for a ROS2 action type. This is useful for understanding what parameters an action accepts before invoking it.
Parameters:
actionType(string) - The action type from discovery (e.g., 'nav2_msgs/action/NavigateToPose')
Returns: Promise<Object> - Structure information with goal, result, and feedback fields
// JavaScript - First discover actions, then use the 'type' field
const actions = await oloClient.core.listActions();
const action = actions.find(a => a.name === '/navigate_to_pose');
// Use action.type (NOT action.name)
const structure = await oloClient.core.getActionGoalStructure(action.type);
console.log('Goal fields:', structure.goal);
console.log('Result fields:', structure.result);
console.log('Feedback fields:', structure.feedback);sendActionGoal(actionName, actionType, goal, options)
Send a goal to a ROS2 action server. This method returns immediately with a goal handle that can be used to cancel the action. Use callbacks to receive feedback and results.
Parameters:
actionName(string) - The action server name (e.g., '/my_action')actionType(string) - The action type (e.g., 'my_pkg/action/MyAction')goal(object) - The goal message valuesoptions(object, optional) - Additional options:onFeedback(function) - Callback for feedback messages:(feedback) => voidonResult(function) - Callback for result:(result, status) => voidtimeout(number) - Timeout in milliseconds (JavaScript) or seconds (Python)
Returns: Promise<{goalId: string, cancel: function}> - Goal handle with cancel function
Status values: 'succeeded', 'cancelled', 'aborted', 'timeout', 'unknown'
// JavaScript - Send goal with feedback
const handle = await oloClient.core.sendActionGoal(
'/my_action',
'my_pkg/action/MyAction',
{ /* goal fields based on action structure */ },
{
onFeedback: (feedback) => {
console.log('Progress:', feedback);
},
onResult: (result, status) => {
console.log('Completed with status:', status);
console.log('Result:', result);
},
timeout: 60000 // 60 seconds
}
);
console.log('Goal started with ID:', handle.goalId);
// Cancel the action if needed
// handle.cancel();cancelActionGoal(actionName, goalId)
Cancel an active action goal.
Parameters:
actionName(string) - The action server namegoalId(string) - The goal ID to cancel
Returns: Promise<boolean> - True if cancel message was sent
// JavaScript
const handle = await oloClient.core.sendActionGoal('/my_action', 'my_pkg/action/MyAction', goal);
// Later, cancel the action
await oloClient.core.cancelActionGoal('/my_action', handle.goalId);callAction(actionName, actionType, goal, options)
Call a ROS2 action and wait for the result. This is a convenience method that sends a goal and blocks until completion. Use this for simpler fire-and-wait scenarios.
Parameters:
actionName(string) - The action server nameactionType(string) - The action typegoal(object) - The goal message valuesoptions(object, optional) - Additional options:onFeedback(function) - Optional callback for feedback messagestimeout(number) - Timeout in milliseconds (JS) or seconds (Python). Default: 60000ms / 60s
Returns: Promise<{result: object, status: string}> - Action result and final status
Throws: Error if action is cancelled, aborted, or times out
// JavaScript - Simple action call
try {
const { result, status } = await oloClient.core.callAction(
'/my_action',
'my_pkg/action/MyAction',
{ /* goal fields */ },
{
onFeedback: (fb) => console.log('Progress:', fb),
timeout: 30000
}
);
console.log('Action complete! Status:', status);
} catch (err) {
console.error('Action failed:', err.message);
}Action Discovery Workflow
A typical workflow for working with actions on your robot:
// 1. Discover available actions
const actions = await oloClient.core.listActions();
console.log('Found', actions.length, 'action servers');
// List them
for (const action of actions) {
console.log(' ', action.name, '->', action.type || 'unknown');
}
// 2. Find an action with a known type
const targetAction = actions.find(a => a.type && a.type !== 'unknown');
if (!targetAction) {
console.log('No actions with known types found');
return;
}
// 3. Get the goal structure to understand required fields
const structure = await oloClient.core.getActionGoalStructure(targetAction.type);
console.log('Action requires:', structure.goal);
// 4. Invoke the action with proper parameters
const { result, status } = await oloClient.core.callAction(
targetAction.name,
targetAction.type,
{ /* fill in goal fields based on structure */ }
);
console.log('Action completed:', status);