Module reference · Cross-cutting
Task Goal & Termination
The module that checks a study's stopping rules and ends the trial when the first one is met.
What
The module coordinates task completion, failure, timeout, and abort rules. It does not define one universal task. Instead, a study attaches one or more TaskTerminationCriterion components, and each criterion decides whether its own terminal condition has been reached.
A criterion returns a TrialTerminationResult with one of four outcomes: Success, Failure, Timeout, or Abort. The first result becomes the timestamped trial-ended event that other study modules can record.
Why
The paper's DR6 separates task and environment content from the rules that end a trial. The condition scene owns terrain, obstacles, lighting, and visible goal content. This module owns the executable rules that determine when the participant has completed the task or when the trial must stop.
This keeps the same teleoperation apparatus reusable across tasks. A goal-entry criterion, collision criterion, time limit, or operator abort can be selected without changing communication, vehicle behavior, observation streams, or presentation.
How
Each termination criterion watches one stopping rule. The flow below shows how current vehicle and task state becomes a terminal result and an event for the rest of the study.
trial-ended eventoutcome and reason for other modules- Check each rule. A criterion evaluates its own condition against the current vehicle and task state.
- End the trial. When a criterion returns
Success,Failure,Timeout, orAbort, the module ends the trial. - Notify the study. The module publishes
trial-endedwith the outcome and reason so other study modules can react or record it.
If multiple criteria become true in the same update, their Inspector order determines which result wins. In the shipped demo, target entry comes before the 300-second timeout.
Boundary
Owns
- Evaluating the configured termination criteria against current vehicle and task state.
- Choosing the first terminal result in the configured criterion order.
- Publishing the
trial-endedevent with the outcome and reason.
Does not own
- Creating the terrain, obstacles, lighting, or visible goal content in the condition scene.
- Changing the vehicle or deciding the authoritative remote state.
- Writing study data or calculating metrics — Data Capture & Logging's job.
Contract
Study code extends TaskTerminationCriterion, reads its declared dependencies, and returns a TrialTerminationResult when its condition is met. The task module itself is configured in the Unity Inspector.
using UnityEngine;
public abstract class TaskTerminationCriterion : MonoBehaviour
{
protected abstract bool TryEvaluate(
double timestampSeconds,
out TrialTerminationResult result);
}Configure the kernel module and its criteria through the Unity Inspector. The module reports the lifecycle result through TeleroboticsAgent.TrialEnded. Data Capture & Logging may subscribe to that event; the task module does not write study data.
Success,Failure,Timeout, andAbortare lifecycle outcomes.- The criterion supplies the outcome and reason; the kernel coordinates evaluation and trial shutdown.
- Study-specific logging belongs in a
DataCaptureImplementation.
Examples
The two criteria read the same Lunar-Target-300s task configuration and produce different terminal outcomes.
TargetRegionEntry succeeds when every corner of the authoritative robot bounds is inside the configured target circle. The visible target marker is authored separately in the condition scene.
public sealed partial class TargetRegionEntry
: TaskTerminationCriterion
{
[SerializeField] private Transform authoritativeRobot;
[SerializeField] private EveryMoveTaskConfiguration configuration;
[SerializeField, Min(0f)] private float detectionTolerance = 0.15f;
private Renderer[] robotRenderers = Array.Empty<Renderer>();
private void Start()
{
if (authoritativeRobot)
robotRenderers = authoritativeRobot.GetComponentsInChildren<Renderer>(true);
}
protected override bool TryEvaluate(
double timestamp,
out TrialTerminationResult result)
{
result = null;
if (!authoritativeRobot || !configuration)
return false;
if (!IsRobotOverTarget())
return false;
result = new TrialTerminationResult(
TrialTerminationOutcome.Success,
"target-region-entry");
return true;
}
private bool IsRobotOverTarget()
{
float effectiveRadius =
configuration.targetRadius + detectionTolerance;
Bounds bounds;
if (!TryGetRobotBounds(out bounds))
{
bounds = new Bounds(
authoritativeRobot.position,
new Vector3(0.35f, 0.14f, 0.22f));
}
Vector2 target = new Vector2(
configuration.targetCenter.x,
configuration.targetCenter.z);
Vector3 center = bounds.center;
Vector3 extents = bounds.extents;
Vector2[] corners =
{
new Vector2(center.x - extents.x, center.z - extents.z),
new Vector2(center.x + extents.x, center.z - extents.z),
new Vector2(center.x - extents.x, center.z + extents.z),
new Vector2(center.x + extents.x, center.z + extents.z)
};
for (int index = 0; index < corners.Length; index++)
{
if (Vector2.Distance(corners[index], target) > effectiveRadius)
return false;
}
return true;
}
private bool TryGetRobotBounds(out Bounds bounds)
{
bounds = default;
bool found = false;
for (int index = 0; index < robotRenderers.Length; index++)
{
Renderer renderer = robotRenderers[index];
if (!renderer || !renderer.enabled)
continue;
if (!found)
{
bounds = renderer.bounds;
found = true;
}
else
{
bounds.Encapsulate(renderer.bounds);
}
}
return found;
}
}ElapsedTimeLimit starts its timer on the first evaluation and returns Timeout when the configured duration has elapsed.
public sealed partial class ElapsedTimeLimit
: TaskTerminationCriterion
{
[SerializeField] private EveryMoveTaskConfiguration configuration;
private double startedAt = -1d;
protected override bool TryEvaluate(
double timestamp,
out TrialTerminationResult result)
{
if (startedAt < 0d)
startedAt = timestamp;
result = null;
if (!configuration ||
timestamp - startedAt < configuration.timeLimitSeconds)
return false;
result = new TrialTerminationResult(
TrialTerminationOutcome.Timeout,
"elapsed-time-limit");
return true;
}
}A timeout is a terminal result, not a second attempt to complete the goal. Once emitted, the agent is no longer active.
Config
Configure the task through the Unity Inspector. The module coordinates the lifecycle; concrete criterion components provide the rules.
- Add one
TaskGoalAndTerminationModuleto theTeleroboticsAgentGameObject. - Add one component derived from
TaskTerminationCriterionfor each terminal rule, such asTargetRegionEntryorElapsedTimeLimit. - Assign each criterion's serialized references, such as the authoritative robot and task configuration.
- Drag the criterion components into the module's
criteriaarray in priority order. - Keep the visible goal marker, terrain, and other environment content in the condition scene. The task module evaluates those dependencies but does not own or draw them.