Skip to content

Commit

Permalink
Merge pull request #20 from rwth-acis/feature/taskQueueControl
Browse files Browse the repository at this point in the history
Feature/task queue control
  • Loading branch information
BenediktHensen authored Oct 7, 2024
2 parents 6e2be28 + 4a3b1ca commit 9e43bd4
Show file tree
Hide file tree
Showing 14 changed files with 249 additions and 10 deletions.
9 changes: 9 additions & 0 deletions Assets/Virtual Agents Framework/Runtime/Scripts/BaseTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ public void StopAsFailed()
StopExecution();
}

/// <summary>
/// Can be used to abort the task outside of its Update method
/// </summary>
public void StopAsAborted()
{
State = TaskState.Aborted;
StopExecution();
}

/// <summary>
/// Can be used to let the task succseed outside of its Update method
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace i5.VirtualAgents.AgentTasks
{
/// <summary>
/// Starts or stops adaptive gaze on the agent and marks the task as completet afterwards.
/// Starts or stops adaptive gaze on the agent and marks the task as completed afterwards.
/// </summary>
public class AgentAdaptiveGazeTask : AgentBaseTask, ISerializable
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,5 +140,14 @@ public void Deserialize(SerializationDataContainer serializer)
playTime = serializer.GetSerializedFloat("Play Time");
}

/// <summary>
/// Aborts the animation task and sets its state to aborted
/// </summary>
public override void Abort()
{
StopExecution();
State = TaskState.Aborted;
}

}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using i5.Toolkit.Core.Utilities;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace i5.VirtualAgents.AgentTasks
{
Expand Down Expand Up @@ -96,5 +97,16 @@ public void WaitFor(params AgentBaseTask[] otherTasks)
}
}
}

/// <summary>
/// Aborts the task and sets its state to aborted
/// </summary>
public virtual void Abort()
{
if (State == TaskState.Running)
{
StopAsAborted();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -202,5 +202,17 @@ public void Deserialize(SerializationDataContainer serializer)
TargetSpeed = serializer.GetSerializedFloat("TargetSpeed");
//FollowingGameObject = serializer.GetSerializedBool("FollowingGameObject");
}

/// <summary>
/// Aborts the movement task and sets its state to aborted
/// </summary>
public override void Abort()
{
if (navMeshAgent != null)
{
StopExecution();
}
State = TaskState.Aborted;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ public class AgentWaitTask : AgentBaseTask, ISerializable
/// </summary>
public float WaitTimeInSeconds { get; set; }

private Coroutine waitCoroutine;

private Agent agent;

public AgentWaitTask() { }

/// <summary>
Expand All @@ -32,6 +36,7 @@ public AgentWaitTask(float timeInSeconds)
/// <param name="agent">The agent which executes this task</param>
public override void StartExecution(Agent agent)
{
this.agent = agent;
base.StartExecution(agent);

if (WaitTimeInSeconds <= 0)
Expand All @@ -47,8 +52,7 @@ public override void StartExecution(Agent agent)
FinishTaskAsFailed();
return;
}

agent.StartCoroutine(Wait(WaitTimeInSeconds));
waitCoroutine = agent.StartCoroutine(Wait(WaitTimeInSeconds));
}

// wait for the given time and then finish the task
Expand All @@ -58,14 +62,27 @@ private IEnumerator Wait(float timeInSeconds)
FinishTask();
}

public void Serialize(SerializationDataContainer serializer)
public void Serialize(SerializationDataContainer serializer)
{
serializer.AddSerializedData("Wait time", WaitTimeInSeconds);
}

public void Deserialize(SerializationDataContainer serializer)
public void Deserialize(SerializationDataContainer serializer)
{
WaitTimeInSeconds = serializer.GetSerializedFloat("Wait time");
}

/// <summary>
/// Aborts the wait task
/// </summary>
public override void Abort()
{
if (waitCoroutine != null)
{
agent.StopCoroutine(waitCoroutine);
waitCoroutine = null;
}
State = TaskState.Aborted;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ public interface IAgentTask : ITask
/// </summary>
bool CanStart { get; }

/// <summary>
/// Aborts the task
/// </summary>
public void Abort() {}

event Action OnTaskFinished;
event Action OnTaskStarted;
}
Expand Down
3 changes: 2 additions & 1 deletion Assets/Virtual Agents Framework/Runtime/Scripts/ITask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ public enum TaskState
Waiting, // Task created, but never executed
Running, // Task currently running
Failure, // Task has finished executing and failed
Success // Task has finished executing and succeeded
Success, // Task has finished executing and succeeded
Aborted // Task has been aborted
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using i5.Toolkit.Core.Utilities;
using System;
using i5.VirtualAgents.AgentTasks;
using UnityEngine;
using System.Linq;

namespace i5.VirtualAgents.ScheduleBasedExecution
Expand Down Expand Up @@ -234,5 +235,48 @@ public TaskState CheckTaskQueueStates()
return IsActive ? TaskState.Running : TaskState.Waiting;

}

/// <summary>
/// Removes all tasks from the queue and sets the state of the task manager to idle
/// </summary>
/// <param name="clearCurrentTask">Determines whether the current task should be aborted as well</param>
public void Clear(bool clearCurrentTask)
{
queue.Clear();
if (clearCurrentTask)
{
CurrentTask.Abort();
CurrentTask = null;
CurrentState = TaskManagerState.idle;
}
lastTask = null;
}

/// <summary>
/// Removes a task from the task queue
/// </summary>
/// <param name="task">The task to be removed</param>
public void RemoveTask(IAgentTask task)
{
queue.RemoveTask(task);
if (CurrentTask == task)
{
Abort();
}
}

/// <summary>
/// Aborts the current task
/// </summary
public void Abort()
{
if (CurrentTask != null)
{
CurrentTask.Abort();
CurrentTask = null;
CurrentState = TaskManagerState.idle;
}
}

}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using i5.VirtualAgents.AgentTasks;
using UnityEngine;

namespace i5.VirtualAgents.ScheduleBasedExecution
{
Expand Down Expand Up @@ -83,6 +84,30 @@ public struct TaskEntry
public IAgentTask task;
public int priority;
}

/// <summary>
/// Removes all tasks from the queue
/// </summary>
public void Clear()
{
taskQueue.Clear();
}

/// <summary>
/// Removes a task from the task queue
/// </summary>
/// <param name="task">Task to be removed</param>
public void RemoveTask(IAgentTask task)
{
foreach (TaskEntry entry in taskQueue)
{
if (entry.task == task)
{
taskQueue.Remove(entry);
break;
}
}
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,59 @@ public void ScheduleTask(IAgentTask task, int priority = 0, string layer = "Base
{
taskManagers[layer].ScheduleTask(task, priority);
}

/// <summary>
/// Aborts the current task on the specified layer
/// </summary>
/// <param name="layer">Name of the layer on which the task should be aborted</param>
public void Abort(string layer = "Base Layer")
{
taskManagers[layer].Abort();
}

/// <summary>
/// Aborts the current tasks on all layers
/// </summary>
public void AbortAllLayers()
{
foreach (var layer in taskManagers)
{
taskManagers[layer.Key].Abort();
}
}

/// <summary>
/// Removes a given task from the TaskSystem
/// </summary>
/// <param name="task">The task to be removed</param>
/// <param name="layer">The layer on which the given task resides</param>
public void RemoveTask(IAgentTask task, string layer = "Base Layer")
{
taskManagers[layer].RemoveTask(task);
}

/// <summary>
/// Clears all tasks from the given layer
/// </summary>
/// <param name="layer">The layer whose tasks should be cleared, leave empty to clear base layer.</param>
/// <param name="clearCurrentTask">If true, the current tasks gets aborted and removed as well, otherwise it can still finish.
/// By default set to true</param>
public void Clear(string layer = "Base Layer", bool clearCurrentTask = true)
{
taskManagers[layer].Clear(clearCurrentTask);
}

/// <summary>
/// Clears all tasks from all layers
/// </summary>
/// <param name="clearCurrentTask">If true, the current tasks gets aborted and removed as well, otherwise it can still finish.
/// By default set to true</param>
public void ClearAllLayers(bool clearCurrentTask = true)
{
foreach (var layer in taskManagers)
{
taskManagers[layer.Key].Clear(clearCurrentTask);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Collections;
using i5.VirtualAgents.ScheduleBasedExecution;
using System.Collections.Generic;
using i5.VirtualAgents.AgentTasks;
using UnityEngine;

namespace i5.VirtualAgents.Examples
Expand All @@ -17,22 +19,30 @@ public class AgentNavigationController : SampleScheduleController
/// </summary>
[Tooltip("Waypoint with a high priority")]
public Transform highPrioWaypoint;

private AgentBaseTask removeTask;
protected override void Start()
{
base.Start();
// add walking tasks for each waypoint
// here, we use the TaskActions shortcut but we could also just create a new
// AgentMovementTask and schedule it using agent.ScheduleTask.
for (int i = 0; i < waypoints.Count; i++)
for (int i = 0; i < waypoints.Count-1; i++)
{
taskSystem.Tasks.GoTo(waypoints[i].position);
}
// this task will never be executed, as we remove it before it is started
removeTask = taskSystem.Tasks.GoTo(waypoints[^1].position);

// example for a different priority:
// this waypoint is added last but has the highest priority,
// so the agent will walk to it first
taskSystem.Tasks.GoTo(highPrioWaypoint, Vector3.zero, 5);

// we can retroactively remove tasks from the queue
// tasks that are already running will be aborted
// to remove all tasks one can use taskSystem.Clear()
taskSystem.RemoveTask(removeTask);
}

}
}
Loading

0 comments on commit 9e43bd4

Please sign in to comment.