Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

1,068 views

Published on

  • Be the first to comment

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

  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 />

×