Advertisement

Suspending a goal

Started by November 11, 2008 10:27 AM
5 comments, last by wodinoneeye 16 years ago
Hello, I'm working on an AI system just like the goal-based one in Mat Buckland's book "Programming AI by example". The system uses "atomic goals" and "composite goals", where composite goals can have subgoals. In this system, a goal to control path following is called GoalFollowPath and it has (atomic) subgoals called GoalTraversePathEdge. This makes it easy to interrupt movement by inserting an interruption goal such as "GoalDefendFromAttack" as the next goal to execute after the current GoalTraversePathEdge. After the threat has been dealt with, the agent resumes movement. A downside is that the GoalDefendFromAttack has to wait until the current GoalTraversePathEdge has finished which might take a few seconds. So the reaction time of the agent will be slow. Similarly, I have defined some atomic goals such as GoalProduce and GoalRepair which are basically a timer that runs for the period of time required to execute the task, which could be up to a minute. Adding GoalDefendFromAttack as the next goal to one of these would result in stupid-looking behaviour. How can the system be extended to allow suspension/interruption of atomic goals that I want to be able to resume again?
Have a stack where you push on all goal in reverse order; when you interrupt a goal, push it back on the stack, and push the new (interrupting) goal afterwards.

Your agent should work something like this to work:

Update()
if curGoal.IsFinished()
curGoal = goalStack.Pop()

... (process environment update)
... (execute code for goal)


You will have to have an "idle" goal on the bottom of the stack though.
If the environment update generates a new goal, the current goal is pushed,
then the new goal and the current Goal is made invalid.
The next frame, the new goal will be popped and executed, and once it's finished,
the postponed one will be popped and resumed.
Using your brain doesn't hurt at all.
Advertisement
<unintentional double post>
Using your brain doesn't hurt at all.
The meaning of "atomic" is "that which cannot be split". By that very definition, suspending or interrupting atomic behavior is impossible. So, of course, if you have one-minute atomic actions, then you will invariably spend that minute finishing that action regardless of what happens around you.

Ideally, you would make atomic actions extremely short, so that you don't encounter the "appear stupid because you're not reacting" issue. GoalProduce should be composed of one "start production" atomic action, followed by an infinite number of "wait" atomic actions. When the production is done, the GoalProduce has been reached so you move on to the next. If you're attacked, you replace the GoalProduce with DefendYourself.
Quote: Original post by captain_crunch
Hello,

I'm working on an AI system just like the goal-based one in Mat Buckland's book "Programming AI by example".

The system uses "atomic goals" and "composite goals", where composite goals can have subgoals. In this system, a goal to control path following is called GoalFollowPath and it has (atomic) subgoals called GoalTraversePathEdge.
This makes it easy to interrupt movement by inserting an interruption goal such as "GoalDefendFromAttack" as the next goal to execute after the current GoalTraversePathEdge. After the threat has been dealt with, the agent resumes movement.

A downside is that the GoalDefendFromAttack has to wait until the current GoalTraversePathEdge has finished which might take a few seconds. So the reaction time of the agent will be slow.

Similarly, I have defined some atomic goals such as GoalProduce and GoalRepair which are basically a timer that runs for the period of time required to execute the task, which could be up to a minute.
Adding GoalDefendFromAttack as the next goal to one of these would result in stupid-looking behaviour.

How can the system be extended to allow suspension/interruption of atomic goals that I want to be able to resume again?



Moving an entire length of a PathEdge as atomic might be the problem. Maybe you should break it down further into the movement steps taken (now only a second or less long). Now you have interrupt points much more frequently to allow other tasks to run (or even to cancel the movement task).

--------------------------------------------[size="1"]Ratings are Opinion, not Fact
Thank you for the great suggestions!

lucem, your idea sounds a lot like what I was starting to think about myself. I had an idea about adding a new goal state called 'Suspended' and somehow pass goals in this state over when deciding what goal to process next.

But now I think the problem is that it would introduce extra complexity as well as add an additional option in deciding what to do when reacting to events. With the current system I already need to choose between terminating the current goal, or instead appending the new goal as a subgoal. Now there would be an additional option, namely suspending the current goal. This all makes it harder to program behaviour.

So that is why I like the Toorhvyk's and wodinoneeye's suggestions better. I previously wondered why there was a distinction between atomic and composite goals in the design. By defining atomic goals as very short, there is a real semantic difference that I previously didn't get. So I am going to convert the atomic goals so they are much shorter in duration. And now the agents can react quickly to events without introducing more complexity into the system.
Advertisement

On aspect of an Atomic goal can also be that when it is a primitive action which once started has to be carried thru (And some result possibly produced),
you dont have to do any AI recalculations until its done -- yes you might have to save up environmental sensory inputs, but you cant make a good decision until that action completes (and its result is known) and the full situation at that point in time is known (when the next decision can properly be made).

Even some sequence like swinging a sword can be broken down into multiple steps
(because a good swordsman can change his swords trajectory as a countermove within the swing). Even after strinking (or not) the target the sword is guided to a new position for the strokes/blocks that can follow (and there are many variations of those).

Of course a predetermined sequence can be created as simpler 'swing' action (with no decisions within it that the AI could change). Of course if it is too long it will have 'reality' problems when external actions (by other entities) have to wait till the one action is completed before they can be resolved.

Usually the animation sequencer takes a certain time period to render the action (each primitive) and during that time the AI can sleep (apart from collecting sensor data). The AI is woken up and the next action/reaction is decided.

Of course high-level goals/tasks/solutions can be worked on within the atomic primitive (they can be general enough that the outcome of primitive actions dont bear on their decisions so much ). They also can consume more processing time to resolve than there is in a small game action timeslice , and have to be spread out over many cycles.
--------------------------------------------[size="1"]Ratings are Opinion, not Fact

This topic is closed to new replies.

Advertisement