목적이 부여된 에이전트 행동

835
-1

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
835
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
4
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

목적이 부여된 에이전트 행동

  1. 1. 목적이 부여된 에이전트 행동<br />전효성<br />
  2. 2. 에이전트의 행동 기술 방법<br />FSM기반 아키텍처<br />에이전트 행동 = 상태 + 상태 전이 조건<br />목적 기반 아키텍처<br />에이전트의 행동 = 목적(Goal)들의 집합<br />
  3. 3. 목적<br />단일 목적<br />직접 엔티티 요소를 제어<br />단일 임무, 행위, 행동을 정의<br />예, 위치 찾기, 무기 재장전<br />복합 목적<br />여러 부목적을 순차적 / 선택적으로 수행<br />몇 개의 부 목적으로 구성<br />예, 후퇴하여 엄폐물 찾기<br />
  4. 4. 목적 기반 계획<br />상위 레벨 추상 목적 선택<br />목적을 추상적으로 분해하여 행동계획 만듬<br />순차적<br />선택적 목적<br />예, “극장에 간다”라는 복합 목적의 구조<br />
  5. 5. Dragon Slayer2의 사례<br />
  6. 6. 구현 – 기본 개념<br />Stack을 이용한 Subgoal관리<br />Composite 디자인 패턴<br />
  7. 7. 구현 – 최종 디자인<br />
  8. 8. Goal_Composite::ProcessSubgoals()<br />template <classentity_type><br />intGoal_Composite<entity_type>::ProcessSubgoals()<br />{ <br />while (!m_SubGoals.empty() &&<br /> (m_SubGoals.front()->isComplete() || m_SubGoals.front()->hasFailed())) //실패한 goal이나 성공한 goal제거<br /> { <br />m_SubGoals.front()->Terminate();<br />deletem_SubGoals.front(); <br />m_SubGoals.pop_front();<br /> }<br />if (!m_SubGoals.empty())<br /> { <br />intStatusOfSubGoals = m_SubGoals.front()->Process(); //스택의top에 해당하는 goal을 실행<br />if (StatusOfSubGoals == completed && m_SubGoals.size() > 1) <br /> {<br />return active;<br /> }<br />returnStatusOfSubGoals;<br /> }<br />else<br /> {<br />return completed;<br /> }<br />}<br />
  9. 9. Goal_Composite:: RemoveAllSubgoals()<br />template <classentity_type><br />voidGoal_Composite<entity_type>::RemoveAllSubgoals()<br />{<br />for (SubgoalList::iterator it = m_SubGoals.begin();<br /> it != m_SubGoals.end();<br /> ++it)<br /> { <br /> (*it)->Terminate();<br />delete *it;<br /> }<br />m_SubGoals.clear();<br />}<br />
  10. 10. Raven Bot에서 사용되는 목적들<br />
  11. 11. 단일목적 - Goal_Wander<br />voidGoal_Wander::Activate()<br />{<br />m_iStatus = active;<br />m_pOwner->GetSteering()->WanderOn();<br />}<br />intGoal_Wander::Process()<br />{<br />//if status is inactive, call Activate()<br />ActivateIfInactive();<br />returnm_iStatus;<br />}<br />voidGoal_Wander::Terminate()<br />{<br />m_pOwner->GetSteering()->WanderOff();<br />}<br />
  12. 12. 단일목적 - Goal_TraverseEdge(1/2)<br />//record the time the bot starts this goal<br />m_dStartTime = Clock->GetCurrentTime(); <br />//calculate the expected time required to reach the this waypoint. This value<br />//is used to determine if the bot becomes stuck <br />m_dTimeExpected = m_pOwner->CalculateTimeToReachPosition(m_Edge.Destination());<br />//factor in a margin of error for any reactive behavior<br />staticconstdoubleMarginOfError = 2.0;<br />m_dTimeExpected += MarginOfError;<br />//set the steering target<br />m_pOwner->GetSteering()->SetTarget(m_Edge.Destination());<br />//Set the appropriate steering behavior. If this is the last edge in the path<br />//the bot should arrive at the position it points to, else it should seek<br />if (m_bLastEdgeInPath)<br /> {<br />m_pOwner->GetSteering()->ArriveOn();<br /> }<br />else<br /> {<br />m_pOwner->GetSteering()->SeekOn();<br /> }<br />voidGoal_TraverseEdge::Activate()<br />{<br />m_iStatus = active;<br />//the edge behavior flag may specify a type of movement that necessitates a change in the bot's max possible speed as it follows this edge<br />switch(m_Edge.Behavior())<br /> {<br />caseNavGraphEdge::swim:<br /> {<br />m_pOwner->SetMaxSpeed(script->GetDouble("Bot_MaxSwimmingSpeed"));<br /> }<br />break;<br />caseNavGraphEdge::crawl:<br /> {<br />m_pOwner->SetMaxSpeed(script->GetDouble("Bot_MaxCrawlingSpeed"));<br /> }<br />break;<br /> }<br />이어서<br />
  13. 13. 단일목적 - Goal_TraverseEdge(2/2)<br />intGoal_TraverseEdge::Process()<br />{<br />//if status is inactive, call Activate()<br />ActivateIfInactive();<br />//if the bot has become stuck return failure<br />if (isStuck())<br /> {<br />m_iStatus = failed;<br /> }<br />//if the bot has reached the end of the edge return completed<br />else<br /> { <br />if (m_pOwner->isAtPosition(m_Edge.Destination()))<br /> {<br />m_iStatus = completed;<br /> }<br /> }<br />returnm_iStatus;<br />}<br />voidGoal_TraverseEdge::Terminate()<br />{<br />//turn off steering behaviors.<br />m_pOwner->GetSteering()->SeekOff();<br />m_pOwner->GetSteering()->ArriveOff();<br />//return max speed back to normal<br />m_pOwner->SetMaxSpeed(script->GetDouble("Bot_MaxSpeed"));<br />}<br />
  14. 14. 복합 목적 - Goal_FollowPath<br />목적지까지의 에지 경로를 따라간다.<br />에지별로 따라가는 동작을 정의한다.<br />Example <br />AB로 이동 할 때에는 수영을 한다.<br />DF로 이동 할 때에는 문을 연다.<br />
  15. 15. 복합 목적 - Goal_FollowPath<br />voidGoal_FollowPath::Activate()<br />{<br />m_iStatus = active;<br />//get a reference to the next edge<br />PathEdge edge = m_Path.front();<br />//remove the edge from the path<br />m_Path.pop_front(); <br />switch(edge.Behavior())<br /> {<br />caseNavGraphEdge::normal:<br /> {<br />AddSubgoal(newGoal_TraverseEdge(m_pOwner, edge, m_Path.empty()));<br /> }<br />break;<br />caseNavGraphEdge::goes_through_door:<br /> {<br />//also add a goal that is able to handle opening the door<br />AddSubgoal(newGoal_NegotiateDoor(m_pOwner, edge, m_Path.empty()));<br /> }<br />break;<br />caseNavGraphEdge::jump:<br /> {<br />//add subgoal to jump along the edge<br /> }<br />break;<br />default:<br />throw std::runtime_error("<Goal_FollowPath::Activate>: Unrecognized edge type");<br /> }<br />}<br />intGoal_FollowPath::Process()<br />{<br />//if status is inactive, call Activate()<br />ActivateIfInactive();<br />m_iStatus = ProcessSubgoals();<br />if (m_iStatus == completed && !m_Path.empty())<br /> {<br /> Activate(); <br /> }<br />returnm_iStatus;<br />}<br />
  16. 16. 복합 목적 - Goal_MoveToPosition<br />voidGoal_MoveToPosition::Activate()<br />{<br />m_iStatus = active;<br />//make sure the subgoal list is clear.<br />RemoveAllSubgoals();<br />if (m_pOwner->GetPathPlanner()->RequestPathToPosition(m_vDestination))<br /> {<br />AddSubgoal(newGoal_SeekToPosition(m_pOwner, m_vDestination));<br /> }<br />}<br />intGoal_MoveToPosition::Process()<br />{<br />//if status is inactive, call Activate()<br />ActivateIfInactive();<br />//process the subgoals<br />m_iStatus = ProcessSubgoals();<br />//if any of the subgoals have failed then this goal re-plans<br />ReactivateIfFailed();<br />returnm_iStatus;<br />}<br />boolGoal_MoveToPosition::HandleMessage(const Telegram& msg)<br />{<br />//first, pass the message down the goal hierarchy<br />boolbHandled = ForwardMessageToFrontMostSubgoal(msg);<br />//if the msg was not handled, test to see if this goal can handle it<br />if (bHandled == false)<br /> {<br />switch(msg.Msg)<br /> {<br />caseMsg_PathReady:<br />//clear any existing goals<br />RemoveAllSubgoals();<br />AddSubgoal(newGoal_FollowPath(m_pOwner, m_pOwner->GetPathPlanner()->GetPath()));<br />returntrue; //msg handled<br />caseMsg_NoPathAvailable:<br />m_iStatus = failed;<br />returntrue; //msg handled<br />default: returnfalse;<br /> }<br /> }<br />returntrue;<br />}<br />
  17. 17. 복합 목적 - Goal_AttackTarget<br />voidGoal_AttackTarget::Activate()<br />{<br />m_iStatus = active;<br />RemoveAllSubgoals();<br />if (!m_pOwner->GetTargetSys()->isTargetPresent())<br /> {<br />m_iStatus = completed;<br />return;<br /> }<br />if (m_pOwner->GetTargetSys()->isTargetShootable())<br /> {<br /> Vector2D dummy;<br />if (m_pOwner->canStepLeft(dummy) || m_pOwner->canStepRight(dummy))<br /> {<br />AddSubgoal(newGoal_DodgeSideToSide(m_pOwner));<br /> }<br />else<br /> {<br />AddSubgoal(newGoal_SeekToPosition(m_pOwner, m_pOwner->GetTargetBot()->Pos()));<br /> }<br /> }<br />else<br /> {<br />AddSubgoal(newGoal_HuntTarget(m_pOwner));<br /> }<br />}<br />intGoal_AttackTarget::Process()<br />{<br />ActivateIfInactive();<br />m_iStatus = ProcessSubgoals();<br />ReactivateIfFailed();<br />returnm_iStatus;<br />}<br />
  18. 18. 목적중재 (Goal_Think)<br />Goal_Think를 통하여 가장 적절한 전략을 선택<br />선택 가능한 전략들<br />무기 얻기 - 로켓 발사기<br />무기 얻기 - 샷건<br />무기 얻기 - 레일건<br />목표 공격하기<br />건강 얻기<br />탐험하기<br />
  19. 19. 전략 평가 구조<br />평가 함수<br />Raven_Feature<br />staticdouble Health(Raven_Bot* pBot)<br />staticdoubleDistanceToItem(Raven_Bot* pBot, intItemType)<br />staticdoubleIndividualWeaponStrength(Raven_Bot* pBot, intWeaponType)<br />staticdoubleTotalWeaponStrength(Raven_Bot* pBot)<br />
  20. 20. 목적을 어떻게 선택할 것인가?<br />전략적 요소의 구현 방법<br />다양한 평가 함수 이용<br />내가 공격 하는 것이 유리한가?<br />후퇴하는 것이 유리한가?<br />목표점으로 이동하는 것이 유리한가?<br />가장 적절한 전략<br />공격 평가 점수<br />0.3<br />후퇴 평가 점수<br />0.1<br />이동 평가 점수<br />0.7<br />
  21. 21. HP아이템 찾기<br />맵 탐색하기<br />특정 지역에 무기 얻기<br />공격 목표 찾기<br />전략 평가 함수<br />0.5<br />or<br />
  22. 22. 전략 평가 소스코드<br />voidGoal_Think::Arbitrate()<br />{<br />double best = 0;<br />Goal_Evaluator* MostDesirable = 0;<br />//iterate through all the evaluators to see which produces the highest score<br />GoalEvaluators::iteratorcurDes = m_Evaluators.begin();<br />for (curDes; curDes != m_Evaluators.end(); ++curDes)<br /> {<br />doubledesirabilty = (*curDes)->CalculateDesirability(m_pOwner);<br />if (desirabilty >= best)<br /> {<br /> best = desirabilty;<br />MostDesirable = *curDes;<br /> }<br /> }<br /> assert(MostDesirable && "<Goal_Think::Arbitrate>: no evaluator selected");<br />MostDesirable->SetGoal(m_pOwner);<br />}<br />
  23. 23. 부산물<br />개성의 표현<br />Goal_Evaluator의 subclass에 bias부여<br />상태 메모리<br />Stack구조를 이용해 이전 내용 기억함<br />명령 큐잉<br />FollowPosition의 Queue로 된 경로점 리스트<br />스크립트 행동에 큐 사용하기<br />List구조의 Subgoals를 통하여 절차적인 흐름을 기술 할 수 있다.<br />
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×