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

23
목목목 목목목 목목목목 목목 목목목

Upload: hyosung-jeon

Post on 12-May-2015

745 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: 목적이 부여된 에이전트 행동

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

전효성

Page 2: 목적이 부여된 에이전트 행동

에이전트의 행동 기술 방법• FSM 기반 아키텍처–에이전트 행동 = 상태 + 상태 전이 조건

• 목적 기반 아키텍처–에이전트의 행동 = 목적 (Goal) 들의 집합

Page 3: 목적이 부여된 에이전트 행동

목적• 단일 목적

– 직접 엔티티 요소를 제어– 단일 임무 , 행위 , 행동을 정의– 예 , 위치 찾기 , 무기 재장전

• 복합 목적– 여러 부목적을 순차적 /

선택적으로 수행– 몇 개의 부 목적으로 구성– 예 , 후퇴하여 엄폐물 찾기

Page 4: 목적이 부여된 에이전트 행동

목적 기반 계획1. 상위 레벨 추상 목적 선택2. 목적을 추상적으로 분해하여 행동계획 만듬

예 , “ 극장에 간다”라는 복합 목적의 구조

순차적

선택적 목적

Page 5: 목적이 부여된 에이전트 행동

Dragon Slayer2 의 사례

Page 6: 목적이 부여된 에이전트 행동

구현 – 기본 개념

Composite 디자인 패턴

Stack 을 이용한 Subgoal 관리

Method 역할Activate •초기화 논리 수행

Process •목적의 상태 갱신•상태 ={failed, completed, active, inactive}

Terminate •정리 작업 수행

Page 7: 목적이 부여된 에이전트 행동

구현 – 최종 디자인

Page 8: 목적이 부여된 에이전트 행동

Goal_Composite::ProcessSubgoals()

template <class entity_type>int Goal_Composite<entity_type>::ProcessSubgoals(){ while (!m_SubGoals.empty() && (m_SubGoals.front()->isComplete() || m_SubGoals.front()->hasFailed())) // 실패한 goal 이나 성공한 goal 제거 { m_SubGoals.front()->Terminate(); delete m_SubGoals.front(); m_SubGoals.pop_front(); }

if (!m_SubGoals.empty()) { int StatusOfSubGoals = m_SubGoals.front()->Process(); // 스택의 top 에 해당하는 goal 을 실행

if (StatusOfSubGoals == completed && m_SubGoals.size() > 1) { return active; } return StatusOfSubGoals; } else { return completed; }}

Page 9: 목적이 부여된 에이전트 행동

Goal_Composite:: RemoveAll-Subgoals()

template <class entity_type>void Goal_Composite<entity_type>::RemoveAllSubgoals(){ for (SubgoalList::iterator it = m_SubGoals.begin(); it != m_SubGoals.end(); ++it) { (*it)->Terminate(); delete *it; } m_SubGoals.clear();}

Page 10: 목적이 부여된 에이전트 행동

Raven Bot 에서 사용되는 목적들

Page 11: 목적이 부여된 에이전트 행동

단일 목적 - Goal_Wandervoid Goal_Wander::Activate(){ m_iStatus = active; m_pOwner->GetSteering()->WanderOn();}

int Goal_Wander::Process(){ //if status is inactive, call Activate() ActivateIfInactive(); return m_iStatus;}

void Goal_Wander::Terminate(){ m_pOwner->GetSteering()->WanderOff();}

Page 12: 목적이 부여된 에이전트 행동

단일 목적 - Goal_TraverseEdge(1/2)void Goal_TraverseEdge::Activate(){ m_iStatus = active; //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 switch(m_Edge.Behavior()) { case NavGraphEdge::swim: { m_pOwner->SetMaxSpeed(script->GetDouble("Bot_MaxSwimmingSpeed")); } break; case NavGraphEdge::crawl: { m_pOwner->SetMaxSpeed(script->GetDouble("Bot_MaxCrawlingSpeed")); } break; }

//record the time the bot starts this goal m_dStartTime = Clock->GetCurrentTime(); //calculate the expected time required to reach the this waypoint. This value //is used to determine if the bot becomes stuck m_dTimeExpected = m_pOwner->CalculateTimeToReachPosition(m_Edge.Destination()); //factor in a margin of error for any reactive behavior static const double MarginOfError = 2.0; m_dTimeExpected += MarginOfError; //set the steering target m_pOwner->GetSteering()->SetTarget(m_Edge.Destination()); //Set the appropriate steering behavior. If this is the last edge in the path //the bot should arrive at the position it points to, else it should seek if (m_bLastEdgeInPath) { m_pOwner->GetSteering()->ArriveOn(); } else { m_pOwner->GetSteering()->SeekOn(); }

이어서

Page 13: 목적이 부여된 에이전트 행동

단일 목적 - Goal_TraverseEdge(2/2)

int Goal_TraverseEdge::Process(){ //if status is inactive, call Activate() ActivateIfInactive(); //if the bot has become stuck return failure if (isStuck()) { m_iStatus = failed; } //if the bot has reached the end of the edge return completed else { if (m_pOwner->isAtPosition(m_Edge.Destination())) { m_iStatus = completed; } } return m_iStatus;}void Goal_TraverseEdge::Terminate(){ //turn off steering behaviors. m_pOwner->GetSteering()->SeekOff(); m_pOwner->GetSteering()->ArriveOff(); //return max speed back to normal m_pOwner->SetMaxSpeed(script->GetDouble("Bot_MaxSpeed"));}

Page 14: 목적이 부여된 에이전트 행동

복합 목적 - Goal_FollowPath

• 목적지까지의 에지 경로를 따라간다 .• 에지별로 따라가는 동작을 정의한다 .– Example • AB 로 이동 할 때에는 수영을 한다 .• DF 로 이동 할 때에는 문을 연다 .

Page 15: 목적이 부여된 에이전트 행동

복합 목적 - Goal_FollowPathvoid Goal_FollowPath::Activate(){ m_iStatus = active; //get a reference to the next edge PathEdge edge = m_Path.front(); //remove the edge from the path m_Path.pop_front(); switch(edge.Behavior()) { case NavGraphEdge::normal: { AddSubgoal(new Goal_TraverseEdge(m_pOwner, edge, m_Path.empty())); } break; case NavGraphEdge::goes_through_door: { //also add a goal that is able to handle opening the door AddSubgoal(new Goal_NegotiateDoor(m_pOwner, edge, m_Path.empty())); } break; case NavGraphEdge::jump: { //add subgoal to jump along the edge } break; default: throw std::runtime_error("<Goal_FollowPath::Activate>: Unrecognized edge type"); }}

int Goal_FollowPath::Process(){ //if status is inactive, call Activate() ActivateIfInactive(); m_iStatus = ProcessSubgoals(); if (m_iStatus == completed && !m_Path.empty()) { Activate(); } return m_iStatus;}

Page 16: 목적이 부여된 에이전트 행동

복합 목적 - Goal_MoveToPositionvoid Goal_MoveToPosition::Activate(){ m_iStatus = active; //make sure the subgoal list is clear. RemoveAllSubgoals(); if (m_pOwner->GetPathPlanner()->RequestPathToPosition(m_vDestination)) { AddSubgoal(new Goal_SeekToPosition(m_pOwner, m_vDestination)); }}int Goal_MoveToPosition::Process(){ //if status is inactive, call Activate() ActivateIfInactive(); //process the subgoals m_iStatus = ProcessSubgoals(); //if any of the subgoals have failed then this goal re-plans ReactivateIfFailed(); return m_iStatus;}

bool Goal_MoveToPosition::HandleMessage(const Tele-gram& msg){ //first, pass the message down the goal hierarchy bool bHandled = ForwardMessageToFrontMostSubgoal(msg); //if the msg was not handled, test to see if this goal can handle it if (bHandled == false) { switch(msg.Msg) { case Msg_PathReady: //clear any existing goals RemoveAllSubgoals(); AddSubgoal(new Goal_FollowPath(m_pOwner, m_pOwner->GetPathPlanner()->GetPath())); return true; //msg handled case Msg_NoPathAvailable: m_iStatus = failed; return true; //msg handled default: return false; } } return true;}

Page 17: 목적이 부여된 에이전트 행동

복합 목적 - Goal_AttackTargetvoid Goal_AttackTarget::Activate(){ m_iStatus = active;

RemoveAllSubgoals(); if (!m_pOwner->GetTargetSys()->isTargetPresent()) { m_iStatus = completed; return; } if (m_pOwner->GetTargetSys()->isTargetShootable()) { Vector2D dummy; if (m_pOwner->canStepLeft(dummy) || m_pOwner->canStepRight(dummy)) { AddSubgoal(new Goal_DodgeSideToSide(m_pOwner)); } else { AddSubgoal(new Goal_SeekToPosition(m_pOwner, m_pOwner->GetTargetBot()->Pos())); } } else { AddSubgoal(new Goal_HuntTarget(m_pOwner)); }}

int Goal_AttackTarget::Process(){ ActivateIfInactive(); m_iStatus = ProcessSubgoals(); ReactivateIfFailed(); return m_iStatus;}

Page 18: 목적이 부여된 에이전트 행동

목적 중재 (Goal_Think)

• Goal_Think 를 통하여 가장 적절한 전략을 선택

• 선택 가능한 전략들–무기 얻기 - 로켓 발사기–무기 얻기 - 샷건–무기 얻기 - 레일건–목표 공격하기–건강 얻기–탐험하기

Page 19: 목적이 부여된 에이전트 행동

전략 평가 구조

Raven_Featurestatic double Health(Raven_Bot* pBot)

static double DistanceToItem(Raven_Bot* pBot, int ItemType)

static double IndividualWeaponStrength(Raven_Bot* pBot, int WeaponType)

static double TotalWeaponStrength(Raven_Bot* pBot)

평가 함수

Page 20: 목적이 부여된 에이전트 행동

목적을 어떻게 선택할 것인가 ?

• 전략적 요소의 구현 방법• 다양한 평가 함수 이용–내가 공격 하는 것이 유리한가 ?–후퇴하는 것이 유리한가 ?–목표점으로 이동하는 것이 유리한가 ?

공격 평가 점수0.3

후퇴 평가 점수0.1

이동 평가 점수0.7

가장 적절한 전략

Page 21: 목적이 부여된 에이전트 행동

특정 지역에 무기 얻기

HP 아이템 찾기

공격 목표 찾기

맵 탐색하기

전략 평가 함수

0.5

or

Page 22: 목적이 부여된 에이전트 행동

전략 평가 소스코드void Goal_Think::Arbitrate(){ double best = 0; Goal_Evaluator* MostDesirable = 0; //iterate through all the evaluators to see which produces the highest score GoalEvaluators::iterator curDes = m_Evaluators.begin(); for (curDes; curDes != m_Evaluators.end(); ++curDes) { double desirabilty = (*curDes)->CalculateDesirability(m_pOwner); if (desirabilty >= best) { best = desirabilty; MostDesirable = *curDes; } } assert(MostDesirable && "<Goal_Think::Arbitrate>: no evaluator selected"); MostDesirable->SetGoal(m_pOwner);}

Page 23: 목적이 부여된 에이전트 행동

부산물• 개성의 표현– Goal_Evaluator 의 subclass 에 bias 부여

• 상태 메모리– Stack 구조를 이용해 이전 내용 기억함

• 명령 큐잉– FollowPosition 의 Queue 로 된 경로점 리스트

• 스크립트 행동에 큐 사용하기– List 구조의 Subgoals 를 통하여 절차적인

흐름을 기술 할 수 있다 .